// 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; } |
English