题目:http://poj.org/problem?id=2299
思路: 树状数组求和,求逆序数对。
CODE:
#include <iostream>
#include <stdio.h>
#include <algorithm>
const int M=500005;
using namespace std;
typedef long long ll;
int a[M],sa[M];
int c[M];
bool cmp(int x,int y)
{
return x<y;
}
int lowbit(int xx)
{
return xx&(-xx);
}
int sum(int x)
{
int s=0;
while(x > 0)
{
s+=c[x];
x-=lowbit(x);
}
return s;
}
void add(int x,int p,int NN)
{
while(x <= NN)
{
c[x]+=p;
x += lowbit(x);
}
}
int main()
{
//freopen("in.in","r",stdin);
int N;
while(~scanf("%d",&N),N)
{
fill(c,c+N+1,0);
fill(a,a+N+1,0);
fill(sa,sa+N+1,0);
for(int i=1;i<=N;i++)
{
scanf("%d",&a[i]);
sa[i]=a[i];
}
sort(sa,sa+N+1,cmp);
ll ans=0;
for(int i=1;i<=N;i++)
{
int pl=lower_bound(sa+1,sa+N+1,a[i])-sa;
add(pl,1,N);
ans +=(ll)(sum(N) - sum(pl));
}
printf("%lld\n",ans);
}
return 0;
}