康托展开的板子题,需要先学习康托展开知识点才能写这个题。
#include <bits/stdc++.h>
#define il inline
using namespace std;
using ll = long long;
using ull = unsigned long long;
using int128=__int128_t;
const ll N = 2e5 + 5, mod =998244353, inf = 2e18;
const double esp=1e-9;
double PI=3.1415926;
il void solve(){
int n,k;
cin>>n>>k;
vector<ll>fact(n+5);
fact[0]=1;
for(int i=1;i<=n;i++)fact[i]=fact[i-1]*i;
auto get_rank=[&](const vector<int>&a)->ll{
ll ans=0;
for(int i=1;i<=n;i++){
ll cnt=0;
for(int j=i+1;j<=n;j++){
cnt+=a[i]>a[j];
}
ans+=cnt*fact[n-i];
}
return ans+1;
};
auto get_v=[&](ll x)->vector<int>{
vector<int>a(n+1);
vector<bool>vis(n+1,false);
for(int i=1;i<=n;i++){
ll now=x/fact[n-i];
x%=fact[n-i];
for(int j=1;j<=n;j++){
if(!vis[j]){
if(now==0){
a[i]=j;
vis[j]=true;
break;
}
now--;
}
}
}
return a;
};
while(k--){
char op;
cin>>op;
if(op=='P'){
ll x;
cin>>x;
auto a=get_v(x-1);
for(int i=1;i<=n;i++){
cout<<a[i]<<" \n"[i==n];
}
}else{
vector<int>a(n+1);
for(int i=1;i<=n;i++)cin>>a[i];
cout<<get_rank(a)<<'\n';
}
}
}
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
// cin >> t;
while (t--) {
solve();
}
return 0;
}

京公网安备 11010502036488号