#include <iostream> #include <cstdio> #include <vector> #include <cstdlib> using namespace std; vector < int > result; int L = 1; long long k; int tab[ 1000000 ]; bool used[ 250000 ]; void change( int a, int b, int left = 0, int right = L, int x = 1 ) { if ( left >= b || right <= a ) return; if ( left >= a && right <= b ) { tab[ x ]--; return; } int mid = ( left + right ) / 2; change( a, b, left, mid, 2 * x ); change( a, b, mid, right, 2 * x + 1 ); } int finder( int x, int n ) { int left = L, mid, right = L + n, sum, h; while ( true ) { mid = ( left + right ) / 2; h = mid; sum = 0; while ( h ) { sum += tab[ h ]; h /= 2; } if ( x == sum && !used[ mid - L ] ) return mid - L; if ( x <= sum ) right = mid; else left = mid + 1; } } bool fun( int n, int v ) { if ( n < 0 ) { if ( --k == 0 ) return true; } else { for ( int i = max( 0, v - n * ( n - 1 ) / 2 ); i <= min( n, v ); ++i ) { result.push_back( i ); if ( fun( n - 1, v - i ) ) return true;; result.pop_back(); } } return false; } int main() { int h, n; scanf( "%d%lld", &n, &k ); while ( L < n ) L *= 2; for ( int i = 0; i < n; ++i ) { tab[ L + i ] = i; } if ( ( n % 4 == 0 || n % 4 == 1 ) && fun( n - 1, n * ( n - 1 ) / 4 ) ) { printf( "TAK\n" ); for ( int i = 0; i < result.size(); ++i ) { //cout << result[ i ]; h = finder( result[ i ], n ); printf( "%d ", h + 1 ); change( h, n ); used[ h ] = true; } } else printf( "NIE\n" ); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | #include <iostream> #include <cstdio> #include <vector> #include <cstdlib> using namespace std; vector < int > result; int L = 1; long long k; int tab[ 1000000 ]; bool used[ 250000 ]; void change( int a, int b, int left = 0, int right = L, int x = 1 ) { if ( left >= b || right <= a ) return; if ( left >= a && right <= b ) { tab[ x ]--; return; } int mid = ( left + right ) / 2; change( a, b, left, mid, 2 * x ); change( a, b, mid, right, 2 * x + 1 ); } int finder( int x, int n ) { int left = L, mid, right = L + n, sum, h; while ( true ) { mid = ( left + right ) / 2; h = mid; sum = 0; while ( h ) { sum += tab[ h ]; h /= 2; } if ( x == sum && !used[ mid - L ] ) return mid - L; if ( x <= sum ) right = mid; else left = mid + 1; } } bool fun( int n, int v ) { if ( n < 0 ) { if ( --k == 0 ) return true; } else { for ( int i = max( 0, v - n * ( n - 1 ) / 2 ); i <= min( n, v ); ++i ) { result.push_back( i ); if ( fun( n - 1, v - i ) ) return true;; result.pop_back(); } } return false; } int main() { int h, n; scanf( "%d%lld", &n, &k ); while ( L < n ) L *= 2; for ( int i = 0; i < n; ++i ) { tab[ L + i ] = i; } if ( ( n % 4 == 0 || n % 4 == 1 ) && fun( n - 1, n * ( n - 1 ) / 4 ) ) { printf( "TAK\n" ); for ( int i = 0; i < result.size(); ++i ) { //cout << result[ i ]; h = finder( result[ i ], n ); printf( "%d ", h + 1 ); change( h, n ); used[ h ] = true; } } else printf( "NIE\n" ); } |