参考了大牛的思路。。
首先 数字0-999999999,数量500000,如果按照常规思路会使用大量内存,因为题中我们只需要数字的大小关系,所以可以sort后根据顺序来进行数据的离散化,节省空间。
另外,用树状数组计算逆序数,所谓逆序数,即该数字后面比它小的数字的数量。在构建树状数组时,先插入数值小的元素。
下面是代码:
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
int n;
const int maxn=500010;
struct Node
{
int val,pos;
}node[maxn];
int c[maxn];
int relax[maxn];
int lowbit(int x)
{
return x&(-x);
}
ll get(int x)
{
int i;
ll sum=0;
for(i=x;i>0;i-=lowbit(i)){
//printf("%d\n",i);
sum+=c[i];
}
return sum;
}
void update(int x)
{
int i;
for(i=x;i<=n;i+=lowbit(i))
{
c[i]+=1;
}
}
bool cmp(const Node& a,const Node& b)
{
return a.val<b.val;
}
int main()
{
while(~scanf("%d",&n)&&n)
{
int i;
for(i=1;i<=n;i++){
scanf("%d",&node[i].val);
node[i].pos=i;
}
sort(node+1,node+n+1,cmp);
for(i=1;i<=n;i++)
{
relax[node[i].pos]=i;
c[i]=0;
}
ll ans=0;
for(i=1;i<=n;i++)
{
update(relax[i]);
//printf("%d\n",relax[i]);
ans+=i-get(relax[i]);
}
printf("%I64d\n",ans);
}
return 0;
}
就这样吧