题目链接:http://poj.org/problem?id=2299
这道题是求逆序数的,离散化+树状数组;
注意的地方:1、离散化的比较函数;2、结果会爆int,所以必须用__int64或者是long long 类型来存储结果;
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN=500000;
int n_case;
int B[MAXN+10],C[MAXN+10];
struct node
{
int index,val;
} A[MAXN+10];
int cmp(const void * a,const void * b) //离散化比较函数模板;这里解决了一些相同的情况
{
return ((node *)a)->val - ((node *)b) ->val;
}
int lowbit(int a) //树状数组的关键地方;
{
return (-a)&a;
}
void insert(int x)
{
for(int i=x; i<MAXN; i+=lowbit(i))
{
C[i]++;
}
}
int getSum(int x)
{
int ans=0;
for(int i=x; i>0; i-=lowbit(i)) ans+=C[i];
return ans;
}
int main()
{
//freopen("in.txt","r",stdin);
long long sum; //用long long存储计算结果;
while(scanf("%d",&n_case)&&n_case!=0)
{
int temp;
sum=0;
for(int i=1; i<=n_case; i++)
{
scanf("%d",&temp);
A[i].val=temp;
A[i].index=i;
}
qsort(A+1,n_case,sizeof(A[0]),cmp);
for(int i=1; i<=n_case; i++)
{
B[A[i].index]=i;
}
memset(C,0,sizeof(C));
for(int i=n_case; i>0; i--) //这里从最后一个开始,查找放进树状数组C里比当前元素小的元素,即 前面所有之和;因为树状数组存储的是逆序数;
{
sum+=getSum(B[i]);
insert(B[i]);
}
printf("%I64d\n",sum);
}
return 0;
}