// Permutacja.cpp : Defines the entry point for the console application. // #include <iostream> #include <vector> #include <algorithm> int main() { long long n, inversionsCount; long long permutationNumber; std::cin >> n >> permutationNumber; inversionsCount = (n*n - n) / 2; if (inversionsCount % 2 || n == 1) { std::cout << "NIE" << std::endl; return 0; } inversionsCount >>= 1; std::vector<std::vector<long long>> mahonianNumbers(n+1); mahonianNumbers[1] = std::vector<long long>({ 1 }); mahonianNumbers[2] = std::vector<long long>({ 1, 1, 0 }); for (int i = 3; i <= n; ++i) { long long maxSize = (i*i - i) / 2 + 1; mahonianNumbers[i] = mahonianNumbers[i - 1]; mahonianNumbers[i].resize(maxSize, 0); for (int j = 1; j < maxSize; ++j) { mahonianNumbers[i][j] += mahonianNumbers[i][j - 1] - (j>=i ? mahonianNumbers[i-1][j - i] : 0); } } /*for (int i = 1; i <= n; ++i) { for (int j = 0; j < mahonianNumbers[i].size(); ++j) { std::cout << mahonianNumbers[i][j] << " "; } std::cout << std::endl; }*/ if (permutationNumber > mahonianNumbers[n][inversionsCount]) { std::cout << "NIE" << std::endl; return 0; } std::cout << "TAK" << std::endl; std::vector<int> resultSet(n); for (int i = 0; i < n; ++i) { resultSet[i] = i + 1; } unsigned int invCount = inversionsCount; for (; n > 2; --n) { unsigned int row = n - 1; unsigned int end = invCount>n ? invCount-n+1: 0; unsigned int j=0; for (auto i = invCount; i > end; --i) { if (permutationNumber <= mahonianNumbers[row][i]) { break; } permutationNumber -= mahonianNumbers[row][i]; ++j; } invCount -= j; std::cout << resultSet[j] << " "; resultSet.erase(resultSet.begin()+j); } if (invCount == 0) { std::cout << resultSet[0] << " " << resultSet[1] << std::endl; } else { std::cout << resultSet[1] << " " << resultSet[0] << std::endl; } 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 | // Permutacja.cpp : Defines the entry point for the console application. // #include <iostream> #include <vector> #include <algorithm> int main() { long long n, inversionsCount; long long permutationNumber; std::cin >> n >> permutationNumber; inversionsCount = (n*n - n) / 2; if (inversionsCount % 2 || n == 1) { std::cout << "NIE" << std::endl; return 0; } inversionsCount >>= 1; std::vector<std::vector<long long>> mahonianNumbers(n+1); mahonianNumbers[1] = std::vector<long long>({ 1 }); mahonianNumbers[2] = std::vector<long long>({ 1, 1, 0 }); for (int i = 3; i <= n; ++i) { long long maxSize = (i*i - i) / 2 + 1; mahonianNumbers[i] = mahonianNumbers[i - 1]; mahonianNumbers[i].resize(maxSize, 0); for (int j = 1; j < maxSize; ++j) { mahonianNumbers[i][j] += mahonianNumbers[i][j - 1] - (j>=i ? mahonianNumbers[i-1][j - i] : 0); } } /*for (int i = 1; i <= n; ++i) { for (int j = 0; j < mahonianNumbers[i].size(); ++j) { std::cout << mahonianNumbers[i][j] << " "; } std::cout << std::endl; }*/ if (permutationNumber > mahonianNumbers[n][inversionsCount]) { std::cout << "NIE" << std::endl; return 0; } std::cout << "TAK" << std::endl; std::vector<int> resultSet(n); for (int i = 0; i < n; ++i) { resultSet[i] = i + 1; } unsigned int invCount = inversionsCount; for (; n > 2; --n) { unsigned int row = n - 1; unsigned int end = invCount>n ? invCount-n+1: 0; unsigned int j=0; for (auto i = invCount; i > end; --i) { if (permutationNumber <= mahonianNumbers[row][i]) { break; } permutationNumber -= mahonianNumbers[row][i]; ++j; } invCount -= j; std::cout << resultSet[j] << " "; resultSet.erase(resultSet.begin()+j); } if (invCount == 0) { std::cout << resultSet[0] << " " << resultSet[1] << std::endl; } else { std::cout << resultSet[1] << " " << resultSet[0] << std::endl; } return 0; } |