#include <vector>
#include <iterator>
#include <iostream>
#include <algorithm>
#include <numeric>
#include <chrono>
template < typename It>
bool next_permutation_bin( It begin, It end)
{
if ( begin == end)
return false ;
It i = begin;
++ i;
if ( i == end)
return false ;
i = end;
-- i;
while ( true )
{
It j = i;
-- i;
if ( * i < * j)
{
auto test = std:: lower_bound ( std:: make_reverse_iterator ( end) ,
std:: make_reverse_iterator ( i) , * i) ;
std:: iter_swap ( i, test) ;
std:: reverse ( j, end) ;
return true ;
}
if ( i == begin)
{
std:: reverse ( begin, end) ;
return false ;
}
}
}
template < typename It>
bool next_permutation( It begin, It end)
{
if ( begin == end)
return false ;
It i = begin;
++ i;
if ( i == end)
return false ;
i = end;
-- i;
while ( true )
{
It j = i;
-- i;
if ( * i < * j)
{
It k = end;
while ( ! ( * i < *-- k) )
/* pass */ ;
iter_swap( i, k) ;
reverse( j, end) ;
return true ;
}
if ( i == begin)
{
reverse( begin, end) ;
return false ;
}
}
}
int bin_test( int n)
{
std:: vector < int > v( n) ;
std:: iota ( v.begin ( ) , v.end ( ) , 1 ) ;
int count = 0 ;
do
{
++ count;
}
while ( :: next_permutation_bin ( v.begin ( ) , v.end ( ) ) ) ;
return count;
}
int std_test( int n)
{
std:: vector < int > v( n) ;
std:: iota ( v.begin ( ) , v.end ( ) , 1 ) ;
int count = 0 ;
do
{
++ count;
}
while ( :: next_permutation ( v.begin ( ) , v.end ( ) ) ) ;
return count;
}
int main( ) {
int count_bin = 0 ;
int count_std = 0 ;
const auto checkPoint0 = std:: chrono :: steady_clock :: now ( ) ;
for ( std:: size_t i = 0 ; i < 100 ; i++ ) {
count_bin = bin_test( 10 ) ;
}
const auto checkPoint1 = std:: chrono :: steady_clock :: now ( ) ;
const std:: size_t time_bin = std:: chrono :: duration_cast < std:: chrono :: milliseconds > ( checkPoint1 - checkPoint0) .count ( ) ;
std:: cout << "time in milliseconds with binary search : " <<
time_bin << std:: endl ;
std:: cout << "number of permutations with binary search : " <<
count_bin << std:: endl ;
const auto checkPoint2 = std:: chrono :: steady_clock :: now ( ) ;
for ( std:: size_t i = 0 ; i < 100 ; i++ ) {
count_std = std_test( 10 ) ;
}
const auto checkPoint3 = std:: chrono :: steady_clock :: now ( ) ;
const std:: size_t time_std = std:: chrono :: duration_cast < std:: chrono :: milliseconds > ( checkPoint3 - checkPoint2) .count ( ) ;
std:: cout << "time in milliseconds with linear search : " <<
time_std << std:: endl ;
std:: cout << "number of permutations with linear search : " <<
count_std << std:: endl ;
return 0 ;
}
I2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGl0ZXJhdG9yPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxhbGdvcml0aG0+CiNpbmNsdWRlIDxudW1lcmljPgojaW5jbHVkZSA8Y2hyb25vPgoKdGVtcGxhdGU8dHlwZW5hbWUgSXQ+CmJvb2wgbmV4dF9wZXJtdXRhdGlvbl9iaW4oSXQgYmVnaW4sIEl0IGVuZCkKewogICAgaWYgKGJlZ2luID09IGVuZCkKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAKICAgIEl0IGkgPSBiZWdpbjsKICAgICsraTsKICAgIGlmIChpID09IGVuZCkKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAKICAgIGkgPSBlbmQ7CiAgICAtLWk7CiAgICAKICAgIHdoaWxlICh0cnVlKQogICAgewogICAgICAgIEl0IGogPSBpOwogICAgICAgIC0taTsKICAgICAgICAKICAgICAgICBpZiAoKmkgPCAqaikKICAgICAgICB7CiAgICAgICAgICAgIGF1dG8gdGVzdCA9IHN0ZDo6bG93ZXJfYm91bmQoc3RkOjptYWtlX3JldmVyc2VfaXRlcmF0b3IoZW5kKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6Om1ha2VfcmV2ZXJzZV9pdGVyYXRvcihpKSwgKmkpOwoKICAgICAgICAgICAgc3RkOjppdGVyX3N3YXAoaSwgdGVzdCk7CiAgICAgICAgICAgIHN0ZDo6cmV2ZXJzZShqLCBlbmQpOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKGkgPT0gYmVnaW4pCiAgICAgICAgewogICAgICAgICAgICBzdGQ6OnJldmVyc2UoYmVnaW4sIGVuZCk7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9Cn0KCnRlbXBsYXRlPHR5cGVuYW1lIEl0Pgpib29sIG5leHRfcGVybXV0YXRpb24oSXQgYmVnaW4sIEl0IGVuZCkKewogICAgaWYgKGJlZ2luID09IGVuZCkKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAKICAgIEl0IGkgPSBiZWdpbjsKICAgICsraTsKICAgIGlmIChpID09IGVuZCkKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAKICAgIGkgPSBlbmQ7CiAgICAtLWk7CiAgICAKICAgIHdoaWxlICh0cnVlKQogICAgewogICAgICAgIEl0IGogPSBpOwogICAgICAgIC0taTsKICAgICAgICAKICAgICAgICBpZiAoKmkgPCAqaikKICAgICAgICB7CiAgICAgICAgICAgIEl0IGsgPSBlbmQ7CiAgICAgICAgICAgIAogICAgICAgICAgICB3aGlsZSAoISgqaSA8ICotLWspKQogICAgICAgICAgICAgICAgLyogcGFzcyAqLzsKICAgICAgICAgICAgCiAgICAgICAgICAgIGl0ZXJfc3dhcChpLCBrKTsKICAgICAgICAgICAgcmV2ZXJzZShqLCBlbmQpOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKGkgPT0gYmVnaW4pCiAgICAgICAgewogICAgICAgICAgICByZXZlcnNlKGJlZ2luLCBlbmQpOwogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQp9CgppbnQgYmluX3Rlc3QoaW50IG4pCnsKICAgIHN0ZDo6dmVjdG9yPGludD4gdihuKTsKICAgIHN0ZDo6aW90YSh2LmJlZ2luKCksIHYuZW5kKCksIDEpOwogICAgCiAgICBpbnQgY291bnQgPSAwOwogICAgCiAgICBkbwogICAgewogICAgICAgICsrY291bnQ7CiAgICB9CiAgICB3aGlsZSAoOjpuZXh0X3Blcm11dGF0aW9uX2Jpbih2LmJlZ2luKCksIHYuZW5kKCkpKTsKICAgIAogICAgcmV0dXJuIGNvdW50Owp9CgppbnQgc3RkX3Rlc3QoaW50IG4pCnsKICAgIHN0ZDo6dmVjdG9yPGludD4gdihuKTsKICAgIHN0ZDo6aW90YSh2LmJlZ2luKCksIHYuZW5kKCksIDEpOwogICAgCiAgICBpbnQgY291bnQgPSAwOwogICAgCiAgICBkbwogICAgewogICAgICAgICsrY291bnQ7CiAgICB9CiAgICB3aGlsZSAoOjpuZXh0X3Blcm11dGF0aW9uKHYuYmVnaW4oKSwgdi5lbmQoKSkpOwogICAgCiAgICByZXR1cm4gY291bnQ7Cn0KCmludCBtYWluKCkgewogICAgCiAgICBpbnQgY291bnRfYmluID0gMDsKICAgIGludCBjb3VudF9zdGQgPSAwOwogICAgCiAgICBjb25zdCBhdXRvIGNoZWNrUG9pbnQwID0gc3RkOjpjaHJvbm86OnN0ZWFkeV9jbG9jazo6bm93KCk7CiAgICAKICAgIGZvciAoc3RkOjpzaXplX3QgaSA9IDA7IGkgPCAxMDA7IGkrKykgewogICAgICAgIGNvdW50X2JpbiA9IGJpbl90ZXN0KDEwKTsKICAgIH0KICAgIAogICAgY29uc3QgYXV0byBjaGVja1BvaW50MSA9IHN0ZDo6Y2hyb25vOjpzdGVhZHlfY2xvY2s6Om5vdygpOwogICAgY29uc3Qgc3RkOjpzaXplX3QgdGltZV9iaW4gPSBzdGQ6OmNocm9ubzo6ZHVyYXRpb25fY2FzdDxzdGQ6OmNocm9ubzo6bWlsbGlzZWNvbmRzPihjaGVja1BvaW50MSAtIGNoZWNrUG9pbnQwKS5jb3VudCgpOwogICAgCiAgICBzdGQ6OmNvdXQgPDwgInRpbWUgaW4gbWlsbGlzZWNvbmRzIHdpdGggYmluYXJ5IHNlYXJjaCA6ICIgPDwKICAgICAgICB0aW1lX2JpbiA8PCBzdGQ6OmVuZGw7CiAgICAKICAgIHN0ZDo6Y291dCA8PCAibnVtYmVyIG9mIHBlcm11dGF0aW9ucyB3aXRoIGJpbmFyeSBzZWFyY2ggOiAiIDw8CiAgICAgICAgY291bnRfYmluIDw8IHN0ZDo6ZW5kbDsKICAgIAogICAgY29uc3QgYXV0byBjaGVja1BvaW50MiA9IHN0ZDo6Y2hyb25vOjpzdGVhZHlfY2xvY2s6Om5vdygpOwogICAgCiAgICBmb3IgKHN0ZDo6c2l6ZV90IGkgPSAwOyBpIDwgMTAwOyBpKyspIHsKICAgICAgICBjb3VudF9zdGQgPSBzdGRfdGVzdCgxMCk7CiAgICB9CiAgICAKICAgIGNvbnN0IGF1dG8gY2hlY2tQb2ludDMgPSBzdGQ6OmNocm9ubzo6c3RlYWR5X2Nsb2NrOjpub3coKTsKICAgIGNvbnN0IHN0ZDo6c2l6ZV90IHRpbWVfc3RkID0gc3RkOjpjaHJvbm86OmR1cmF0aW9uX2Nhc3Q8c3RkOjpjaHJvbm86Om1pbGxpc2Vjb25kcz4oY2hlY2tQb2ludDMgLSBjaGVja1BvaW50MikuY291bnQoKTsKICAgIAogICAgc3RkOjpjb3V0IDw8ICJ0aW1lIGluIG1pbGxpc2Vjb25kcyB3aXRoIGxpbmVhciBzZWFyY2ggOiAiIDw8CiAgICAgICAgdGltZV9zdGQgPDwgc3RkOjplbmRsOwogICAgCiAgICBzdGQ6OmNvdXQgPDwgIm51bWJlciBvZiBwZXJtdXRhdGlvbnMgd2l0aCBsaW5lYXIgc2VhcmNoIDogIiA8PAogICAgICAgIGNvdW50X3N0ZCA8PCBzdGQ6OmVuZGw7CiAgICAKICAgIHJldHVybiAwOwp9