http://acm.hdu.edu.cn/showproblem.php?pid=5775
题意:让一列数进行冒泡排序,问排序过程中,最左边到最右边的差的绝对值。
思路:我感觉,这道题的难点就是用树状数组或者是线段数去求,每个数其后比它小的个数,然后最右边的位置是初始位置加上比它小的个数减去min(初始位置和,最终位置)最小的那个
我是用的树状数组
#include<bits/stdc++.h>
using namespace std;
const int N =2e6;
int a[N],b[N],sum[N],n;
int d[N];
int lowbit(int x)
{
return x&(-x);
}
void update(int x)
{
while(x<=n)
{
sum[x]++;
x+=lowbit(x);
}
}
int query(int x)
{
int ans=0;
while(x)
{
ans+=sum[x];
x-=lowbit(x);
}
return ans;
}
int main()
{
int T,cnt=1;
scanf("%d",&T);
while(T--)
{
memset(sum,0,sizeof(sum));
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
d[a[i]]=i;//d[a[i]]记录原始数据的位子
}
for(int i=n; i>=1; i--)
{
b[a[i]]=query(a[i]);//b[a[i]]//记录a[i]后面比a[i]小的个数
update(a[i]);
}
printf("Case #%d:",cnt++);
for(int i=1; i<=n; i++)
{
printf(" %d",(d[i]+b[i]-min(i,d[i])));
}
printf("\n");
}
return 0;
}