暴力康托展开/逆康托展开即可。时间复杂度
#include <algorithm>
#include <array>
#include <bitset>
#include <iostream>
#include <numeric>
#include <tuple>
#include <vector>
using namespace std;
using ll = long long;
int n;
int k;
void P() {
ll a;
cin >> a;
a--;
vector<int> rk(n);
for (int i = 1; i <= n; i++) {
rk[n - i] = a % i;
a /= i;
}
vector<int> remain(n);
iota(remain.begin(), remain.end(), 1);
for (int i = 0; i < n; i++) {
cout << remain[rk[i]] << ' ';
remain.erase(remain.begin() + rk[i]);
}
cout << '\n';
}
void Q() {
vector<int> remain(n);
iota(remain.begin(), remain.end(), 1);
ll res = 0;
for (int i = 0; i < n; i++) {
int a;
cin >> a;
a = lower_bound(remain.begin(), remain.end(), a) - remain.begin();
res = res * (n - i) + a;
remain.erase(remain.begin() + a);
}
cout << res + 1 << '\n';
}
void Solve() {
char op;
cin >> n >> k;
while (k--) {
cin >> op;
if (op == 'P') {
P();
continue;
}
Q();
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
Solve();
return 0;
}

京公网安备 11010502036488号