康托展开小结-

 

顺 阶乘乘上当前没用过的
逆 除以+1 为当前的数 +% 注意讨论用过没有

可约等于哈希 记录状态

代码

 

 

//
#include<bits/stdc++.h>
using namespace std;
long long n,m;
long long s[110];
long long p[110]= {1,1,2,6,24,120,720,5040,40320,362880};
long long pp[110]= {1,1,2,6,24,120,720,5040,40320,362880};
long long ss[120];
char a[20000];
long long x;
void nikangtuo(long long n,long long k,long long ss []) {
	long long i,j,t,flag[15]= {0};
	k--;
	for(long long i=1; i<=n; i++) {
		t=k/pp[n-i];
		for( j=1; j<=n; j++)
			if(!flag[j]) {
				if(t==0) break;
				t--;
			}
		ss[i]=j;
		flag[j]=1;
		k%=p[n-i];
	}
}
long long kangtuo() {
	long long i,j,temp,num;
	num=s[1]*p[n-1]-p[n-1];
	for(long long i=2; i<=n; i++) {
		temp=0;
		for(long long j=1; j<i; j++) {
			if(s[j]<s[i]) temp++;
		}
		num=num+(s[i]-temp-1)*p[n-i];

	}
	return num+1;

}
int main() {
	cin>>n>>m;
	long long q;
	while(m--) {
		cin>>q;
		if(q==1) {
			cin>>a;
			for(long long i=0; i<strlen(a); i++) {
				s[i+1]=a[i]-'0';
			}
			cout<<kangtuo()<<endl;
		} else {
			cin>>x;
			nikangtuo(n,x,ss);
			for(long long i=1; i<=n; i++)
				cout<<ss[i];
			cout<<endl;
		}
	}
}
posted @ 2019-06-18 19:01  ALEZ  阅读(87)  评论(0编辑  收藏  举报