1、http://blog.csdn.net/sdjzping/article/details/20381665
2、题目大意:
有n个数字,定义i<j并且a[i]>a[j]这样的一对数为逆序对,求这个数中有多少逆序对,
3、题目分析
看着题目很简单,但是n=65537,两重for循环找必超时,所以想到了用树状数组,但是交了好几遍都错了,runtime error,原因就是数组中的数字可以到达10^9,数组肯定要超内存,此题需要用到离散化,但是数字之间可能有重复,这一点没考虑到,有wrong 了好几遍,不过终于是改对了,。
4、题目:
5、AC代码:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define N 65540 #define ll long long int n; int c[N]; struct node { int id; int v; }a[N]; node b[N]; int cmp(node a,node b) { return a.v<b.v; } int cmp1(node a,node b) { return a.id<b.id; } int lowbit(int i) { return i&(-i); } void update(int x,int v) { for(int i=x;i<=n;i+=lowbit(i)) { c[i]+=v; } } ll getsum(int x) { ll sum=0; //此处注意需要计算的是比自己小的,所以不包含自己 for(int i=x-1;i>=1;i-=lowbit(i)) { sum+=c[i]; } return sum; } int main() { while(scanf("%d",&n)!=EOF) { memset(c,0,sizeof(c)); for(int i=1;i<=n;i++) { scanf("%d",&a[i].v); a[i].id=i; } sort(a+1,a+n+1,cmp); a[0].v=-1; int k=1; //注意离散化的时候考虑相等的情况 for(int i=1;i<=n;i++) { if(a[i].v!=a[i-1].v) { b[i].id=a[i].id; b[i].v=k++; } else { b[i].id=a[i].id; b[i].v=b[i-1].v; } } sort(b+1,b+n+1,cmp1); ll sum=0; for(int i=n;i>=1;i--) { sum+=getsum(b[i].v); update(b[i].v,1); } printf("%lld\n",sum); } return 0; }