题意:根据题目给的冒泡排序规则,计算每个数字在冒泡排序过程中,到达的最右和最左坐标差
思路:发现,能向右移动的距离是该数右边有多少比他小的数。最左端的距离是min(原本坐标,数值)
右边有多少个比他小的数可以通过树状数组维护一下
#include<bits/stdc++.h>
#define maxn 111111
using namespace std;
int n;
int a[maxn];
int c[maxn];
int b[maxn];
int res[maxn];
int lowbit(int x) {
return x&-x;
}
/**区间修改单点询问**/
/**
add(l-1,-num);add(r,num);
sum(x);
每次修改闭区间lr的值,询问x节点的值
**/
void add(int k,int num) {
while(k) {
b[k]+=num;
k-=lowbit(k);
}
}
int sum(int k) {
int ans=0;
while(k<=n) {
ans+=b[k];
k+=lowbit(k);
}
return ans;
}
int main()
{
int t;
int kase=0;
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
memset(b,0,sizeof b);
memset(res,0,sizeof res);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++) {
int tt=a[i]-sum(a[i])-1;
res[a[i]]=tt;
if(a[i]<i) res[a[i]]+=i-a[i];
add(a[i],-1);
add(n,1);
}
printf("Case #%d:",++kase);
for(int i=1;i<=n;i++)
printf(" %d",res[i]);
printf("\n");
}
return 0;
}