→题目链接←
就是一道裸的康托展开
开始写的时候我发现我并没有写过并且也不太会
然后开始了自己YY
居然一发A了!!!!
代码:
#include<iostream>
#include<cstdio>
#include<bitset>
#define ll long long
using namespace std;
int n,m;
ll num[22];
void cal(){
int sum[22];
for(int i=1; i<=n; i++)sum[i]=i;
ll ans=0;
for(int i=0; i<n; i++){
int x;
scanf("%d",&x);
ans+=(sum[x]-1)*num[n-i-1];
for(int j=x; j<=n; j++)sum[j]--;
}
printf("%lld\n",ans+1);
}
void cal1(ll x){
x--;
int sum[22],ans[22];
bool vis[22];
for(int i=1; i<=n; i++)sum[i]=i,vis[i]=0;
for(int i=0; i<n; i++){
for(int j=n; j>=1; j--){
if(vis[j])continue;
if(x>=(sum[j]-1)*num[n-i-1]){
x-=(sum[j]-1)*num[n-i-1],ans[i]=j;
for(int k=j; k<=n; k++)sum[k]--;
vis[j]=true;
break;
}
}
}
printf("%d",ans[0]);
for(int i=1; i<n; i++){
printf(" %d",ans[i]);
}
printf("\n");
}
int main(){
num[1]=1;
for(int i=2; i<=20; i++)num[i]=num[i-1]*i;
scanf("%d%d\n",&n,&m);
for(int i=0; i<m; i++){
char c=getchar();
if(c=='P'){
ll x;
scanf("%lld",&x);
cal1(x);
}
else{
cal();
}
getchar();
}
return 0;
}