#include <cstdio> #include <cstdint> #include <algorithm> #include <iostream> typedef int64_t int64; int64 MAX; int64 TMP[20000]; class PerSize; PerSize** PER_SIZE; class PerSize { public: int size; int64 maxInv; long* values; int valuesLen; PerSize() { size = 1; maxInv = 0; values = new long[1] {1}; valuesLen = 1; //printf("valuesLen: %d\n", valuesLen); } PerSize(PerSize* other) { //printf("QQQ?\n"); size = other->size + 1; maxInv = ((long)size * (size - 1) / 2); valuesLen = (int)std::min(other->valuesLen + (int64)size, maxInv / 2 + 1); //printf("valuesLen: %d\n", valuesLen); //printf("other->valuesLen: %d\n", other->valuesLen); //printf("maxInv: %ld\n", maxInv / 2 + 1); for (int inv = 1; inv < valuesLen; inv++) { TMP[inv] = other->get(inv) + TMP[inv - 1]; if (TMP[inv] > 2 * MAX) { valuesLen = inv; break; } } for (int inv = valuesLen - 1; inv >= size; inv--) { TMP[inv] -= TMP[inv - size]; } while (TMP[valuesLen - 1] > MAX) { valuesLen--; } //printf("valuesLen: %d\n", valuesLen); values = new long[valuesLen]; for (int i = 0; i < valuesLen; i++) { values[i] = TMP[i]; } } int64 get(int64 idx) { idx = std::min(idx, maxInv - idx); if (idx < 0) { return 0; } return idx < valuesLen ? values[(int)idx] : MAX; } bool solve1(int64 idx, std::vector<int>* result) { return maxInv % 2 == 0 && solve2(this, maxInv / 2, idx - 1, result); } static bool solve2( PerSize* current, int64 base, int64 idx, std::vector<int>* result) { m: while (current->size > 1) { PerSize* previous = PER_SIZE[current->size - 2]; int64 baseStart = std::min(base, previous->maxInv); int64 baseEnd = std::max((int64)0, base - current->size + 1); for (int64 newBase = baseStart; newBase >= baseEnd; newBase--) { int64 v = previous->get(newBase); if (idx < v) { result->push_back((int)(base - newBase)); base = newBase; current = previous; goto m; } idx -= v; } return false; } return true; } }; void print(std::vector<int> result) { std::vector<std::vector<int>> free; int f = 1; for (int q = result.size(); q > 1; q = (q + 1) / 2) { free.emplace_back(std::vector<int>(q, f)); f *= 2; } for (int v : result) { int idx = 0; for (int q = free.size() - 1; q >= 0; q--) { idx *= 2; int onLeft = free[q][idx]; if (v >= onLeft) { idx++; v -= onLeft; } free[q][idx]--; } printf("%d ", (idx + 1)); } printf("\n"); } void solve(int size, int64 idx) { //printf("INIT\n"); MAX = idx + 1; TMP[0] = 1; PER_SIZE = new PerSize*[size]; PER_SIZE[0] = new PerSize(); for (int i = 1; i < size; i++) { PER_SIZE[i] = new PerSize(PER_SIZE[i - 1]); } std::vector<int> result; //printf("SOLVING\n"); if (!PER_SIZE[size - 1]->solve1(idx, &result)) { printf("NIE\n"); return; } printf("TAK\n"); //printf("PRINTING\n"); result.push_back(0); print(result); } int main(int argc, char **argv) { int64 a, b; //scanf("%lli%lli", &a, &b); std::cin >> a >> b; solve(a, b); return 0; }
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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | #include <cstdio> #include <cstdint> #include <algorithm> #include <iostream> typedef int64_t int64; int64 MAX; int64 TMP[20000]; class PerSize; PerSize** PER_SIZE; class PerSize { public: int size; int64 maxInv; long* values; int valuesLen; PerSize() { size = 1; maxInv = 0; values = new long[1] {1}; valuesLen = 1; //printf("valuesLen: %d\n", valuesLen); } PerSize(PerSize* other) { //printf("QQQ?\n"); size = other->size + 1; maxInv = ((long)size * (size - 1) / 2); valuesLen = (int)std::min(other->valuesLen + (int64)size, maxInv / 2 + 1); //printf("valuesLen: %d\n", valuesLen); //printf("other->valuesLen: %d\n", other->valuesLen); //printf("maxInv: %ld\n", maxInv / 2 + 1); for (int inv = 1; inv < valuesLen; inv++) { TMP[inv] = other->get(inv) + TMP[inv - 1]; if (TMP[inv] > 2 * MAX) { valuesLen = inv; break; } } for (int inv = valuesLen - 1; inv >= size; inv--) { TMP[inv] -= TMP[inv - size]; } while (TMP[valuesLen - 1] > MAX) { valuesLen--; } //printf("valuesLen: %d\n", valuesLen); values = new long[valuesLen]; for (int i = 0; i < valuesLen; i++) { values[i] = TMP[i]; } } int64 get(int64 idx) { idx = std::min(idx, maxInv - idx); if (idx < 0) { return 0; } return idx < valuesLen ? values[(int)idx] : MAX; } bool solve1(int64 idx, std::vector<int>* result) { return maxInv % 2 == 0 && solve2(this, maxInv / 2, idx - 1, result); } static bool solve2( PerSize* current, int64 base, int64 idx, std::vector<int>* result) { m: while (current->size > 1) { PerSize* previous = PER_SIZE[current->size - 2]; int64 baseStart = std::min(base, previous->maxInv); int64 baseEnd = std::max((int64)0, base - current->size + 1); for (int64 newBase = baseStart; newBase >= baseEnd; newBase--) { int64 v = previous->get(newBase); if (idx < v) { result->push_back((int)(base - newBase)); base = newBase; current = previous; goto m; } idx -= v; } return false; } return true; } }; void print(std::vector<int> result) { std::vector<std::vector<int>> free; int f = 1; for (int q = result.size(); q > 1; q = (q + 1) / 2) { free.emplace_back(std::vector<int>(q, f)); f *= 2; } for (int v : result) { int idx = 0; for (int q = free.size() - 1; q >= 0; q--) { idx *= 2; int onLeft = free[q][idx]; if (v >= onLeft) { idx++; v -= onLeft; } free[q][idx]--; } printf("%d ", (idx + 1)); } printf("\n"); } void solve(int size, int64 idx) { //printf("INIT\n"); MAX = idx + 1; TMP[0] = 1; PER_SIZE = new PerSize*[size]; PER_SIZE[0] = new PerSize(); for (int i = 1; i < size; i++) { PER_SIZE[i] = new PerSize(PER_SIZE[i - 1]); } std::vector<int> result; //printf("SOLVING\n"); if (!PER_SIZE[size - 1]->solve1(idx, &result)) { printf("NIE\n"); return; } printf("TAK\n"); //printf("PRINTING\n"); result.push_back(0); print(result); } int main(int argc, char **argv) { int64 a, b; //scanf("%lli%lli", &a, &b); std::cin >> a >> b; solve(a, b); return 0; } |