这样考虑:长度为N的排列有N!种全排列。那么长度为N-1的排列有(N-1)!种全排列。那么对于长度为N的排列,第一项为1时有(N-1)!种排列方式,第一项为2时也是(N-1)!种,一直到第一项为n,一共n*(N-1)!种,按字典序升序。那么模拟出每一项是多少即可。假如选定第一项是2,那么后N-1项也是互不相同的数字,可以当成一个排列,之后选定数字为'k'时应是当前备选数字的第k小数字。如此即可模拟出答案。
这里选用set维护备选数字集合。
#include <bits/stdc++.h>
using namespace std;
int main() {
int N,K;
cin>>N>>K;
long long fracs[21];
fracs[0] = 1;
fracs[1] = 1;
for(int i=2;i<=20;i++)fracs[i] = fracs[i-1]*i;
while(K--){
set<int>st;
for(int i=1;i<=N;i++)st.insert(i);
string s;cin>>s;
if(s[0]=='P'){
long long x;cin>>x;
int now = N-1;
auto it = st.begin();
while(now>=0){
while(x>fracs[now]){it++;x-=fracs[now];}
cout << *it << " ";
st.erase(it);
it = st.begin();
now--;
}
}
else{
long long ans = 1;
auto it = st.begin();
for(int i=N-1;i>=0;i--){
int x;cin>>x;
while(*it != x){
it++;
ans += fracs[i];
}
st.erase(it);
it = st.begin();
}
cout << ans;
}
cout << endl;
}
}
// 64 位输出请用 printf("%lld")

京公网安备 11010502036488号