题目链接 http://poj.org/problem?id=2299
题意:大意求冒泡算法需要交换的次数
换个角度就是求逆序数的个数,用线段树可以实现,
先记录一遍数据的位置,然后sort排序,排序后跟新原来位置上的节点,得到相应位置逆序数的个数,具体我也不太还说。。看理解吧
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 5*10e5+10;
int n;
struct Node{//值和位置
int val,pos;
} a[maxn];
int bit[maxn];//树状数组
int cmp(Node x,Node y)
{
return x.val < y.val;
}
int sum(int idx)
{
int s =0;
while(idx>0)
{
s+=bit[idx];
idx -= idx & -idx;
}
return s;
}
void add(int idx,int v)
{
while(idx<=n)
{
bit[idx]+=v;
idx += idx &-idx;
}
}
int main()
{
while(cin>>n&&n)
{
fill(bit,bit+n+1,0);
for(int i=1;i<=n;i++)
cin>>a[i].val,a[i].pos=i;
sort(a+1,a+n+1,cmp);
long long ans = 0;
for(int i=1;i<=n;i++)
{
add(a[i].pos,1);//更新原位置节点
ans += i - sum(a[i].pos);//计算当前位置i的逆序对
}
cout<<ans<<endl;
}
return 0;
}