题意:给定一个k个数字,求第n个全排列,由于n很大,输出的方式为∑Si∗(K−i)!
思路:找规律,输出等于对于每个位置找当前状态下第si小的数。用线段树维护区间和,输入参数查找数字。
const int maxn=50005;
int a[maxn<<2];
void build(int i,int l,int r)
{
if(l==r)
{
a[i]=1;
return ;
}
int mid=(l+r)/2;
build(i*2,l,mid);
build(i*2+1,mid+1,r);
a[i]=a[i*2]+a[i*2+1];
}
int query(int x,int i,int l,int r)
{
if(l==r)
{
a[i]=0;
return l;
}
int ans;
int mid=(l+r)/2;
if(x<=a[i*2]) ans=query(x,i*2,l,mid);
else ans=query(x-a[i*2],i*2+1,mid+1,r);
a[i]=a[i*2]+a[i*2+1];
return ans;
}
int main()
{
int t,n,x;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
build(1,1,n);
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
int ans=query(x+1,1,1,n);
printf("%d%c",ans,i==n?'\n':' ');
}
}
}