//每个数字只会被它后面的比它小的数字影响,且会向右移动相应个数的位置 //比如:6 4 3 5 2 1 。4后面比它小的有 三个,因此它的最右边位置就是当前位置 +3,即5 //如果该数字本身在标准位置左边,那无须考虑,初始位置就是最左端 //如果它在标准位置右边,我们可以知道,它最终肯定要回到标准位置,所以最左边应该为标准位置。 #include<iostream> #include<cstring> using namespace std; const int N=100010; int a[N]; int ans[N]; int tr[N]; int cnt; int lowbit(int x) { return x&-x; } void add(int x,int p) { for(int i=x;i<=N;i+=lowbit(i)) tr[i]+=p; } int sum(int x) { int res=0; for(int i=x;i;i-=lowbit(i)) res+=tr[i]; return res; } int main() { int t; cin>>t; while(t--) { int n; cin>>n; memset(a,0,sizeof a); memset(ans,0,sizeof ans); memset(tr,0,sizeof tr); //输入初始的位置 for(int i=1;i<=n;i++) cin>>a[i]; for(int i=n;i;i--) { //从后往前 //比这个数小的 int res=sum(a[i]); //如果该数字本身在标准位置左边,那无须考虑,初始位置就是最左端 ans[a[i]]=res; //插入该数字到标准位置 add(a[i],1); } //初始位置在标准位置右边,最左端为标准位置,更新|left - right| //a[i]应该在a[i]的位置,但是现在的位置是i,且i>=a[i],说明在标准位置的右边 //那么最左端就是标准位置, for(int i=1;i<=n;i++) if(i>=a[i]) ans[a[i]]+=(i-a[i]); cout<<"Case #"<<++cnt<<":"; for(int i=1;i<=n;i++) cout<<" "<<ans[i]; cout<<endl; } }
原文地址:https://www.cnblogs.com/QingyuYYYYY/p/12288367.html
时间: 2024-11-09 00:07:38