题解:CF1951F Inversion Composition
Caiest_Oier · · 题解
CF1951F
把式子写清楚,就是要你构造一个排列
令
对于贡献固定为
代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
int t,n,k,p[1000003],invp[1000003],q[1000003],lft,rgt;
int lowbit(int X){return (X&(-X));}
class BIT{
public:
int TreeAr[1000003];
void modify(int wz,int val){
wz++;
for(int i=wz;i<=1000000;i+=lowbit(i))TreeAr[i]+=val;
return;
}
int Query(int l,int r){
l++;
r++;
int ret=0;
for(int i=r;i;i-=lowbit(i))ret+=TreeAr[i];
for(int i=l-1;i;i-=lowbit(i))ret-=TreeAr[i];
return ret;
}
}T;
int stk[500003],tot;
signed main(){
ios::sync_with_stdio(false);
cin>>t;
while(t--){
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>p[i];
invp[p[i]]=i;
}
for(int i=0;i<=n+10;i++)T.TreeAr[i]=0;
for(int i=1;i<=n;i++){
k-=T.Query(invp[i]+1,n);
T.modify(invp[i],1);
}
if(k<0||k%2!=0){
cout<<"NO\n";
continue;
}
k/=2;
for(int i=0;i<=n+10;i++)T.TreeAr[i]=0;
T.modify(invp[1],1);
lft=rgt=0;
q[1]=0;
for(int i=2;i<=n;i++){
if(T.Query(1,invp[i]-1)<=k){
k-=T.Query(1,invp[i]-1);
lft--;
q[i]=lft;
}
else{
if(k==0){
for(int j=i;j<=n;j++)q[j]=rgt+(j-i+1);
break;
}
tot=0;
for(int j=1;j<i;j++){
if(invp[j]<invp[i])stk[++tot]=q[j];
}
sort(stk+1,stk+tot+1);
q[i]=stk[tot-k]+1;
for(int j=1;j<i;j++)if(q[j]>stk[tot-k])q[j]++;
rgt++;
k=0;
}
T.modify(invp[i],1);
}
if(k>0){
cout<<"NO\n";
continue;
}
cout<<"YES\n";
for(int i=1;i<=n;i++)cout<<q[i]-lft+1<<" ";
cout<<endl;
}
return 0;
}