逆序数就是数列中各位在它前面有多少个数比它大,求出这些元素个数之和。
求逆序的思路:
可以把数列中的数一个个插入到树状数组中,每插入一个数,统计比他小的数的个数,对应的逆序数为 i-sum(data[i]) ,其中i为当前已经插入的数的个数, sum(data[i]) 为比 data[i] 小的数的个数, i-sum(data[i]) 就是比 data[i] 大的个数,也就是逆序的个数。最后需要把所有逆序数求和,就是在插入的过程中边插入边求和, ans+=i-sum(data[i]) 。
实现源码如下,
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<ctype.h>
#include<algorithm>
using namespace std;
#pragma comment(linker,"/STACK:102400000,102400000")
#define pi acos(-1.0)
#define eps 1e-7
#define mod 1000000007
#define INF 0x3f3f3f3f
typedef long long LL;
int a[1005],n;
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int c)
{
while(x<=n)
{
a[x]+=c;
x+=lowbit(x);
}
}
int sum(int x)
{
int res=0;
while(x>0)
{
res+=a[x];
x-=lowbit(x);
}
return res;
}
int main(void)
{
int i,x,ans;
while(scanf("%d",&n)!=EOF)
{
memset(a,0,sizeof(a));
ans=0;
for(i=1;i<=n;i++)
{
scanf("%d",&x);
update(x,1);
ans+=sum(n)-sum(x);
}
printf("%d\n",ans);
}
return 0;
}