树状数组--求逆序对-离散化
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define ll long long 6 #define MAX 500005 7 using namespace std; 8 9 struct Node 10 { 11 int val,pos; 12 bool operator<(const Node& A)const 13 { 14 return val<A.val; 15 } 16 }d[MAX]; 17 int n,tree[MAX],p[MAX]; 18 19 inline int lowbit(int x) 20 { 21 return x&(-x); 22 } 23 24 void ADD(int pos,int x) 25 { 26 int i=pos; 27 for(;i<=n;i+=lowbit(i)) 28 { 29 tree[i]+=x; 30 } 31 } 32 33 ll Getsum(int N) 34 { 35 ll ans=0; 36 for(int i=N;i>0;i-=lowbit(i)) 37 { 38 ans+=tree[i]; 39 } 40 return ans; 41 } 42 43 int main() 44 { 45 while(~scanf("%d",&n)&&n) 46 { 47 memset(p,0,sizeof(p)); 48 memset(tree,0,sizeof(tree)); 49 for(int i=1;i<=n;i++) 50 { 51 scanf("%d",&d[i].val); 52 d[i].pos=i; 53 } 54 sort(d+1,d+n+1); 55 //对原数组离散化;存到新的数组p中,是源数组的一一映射; 56 int num=1; 57 p[d[1].pos]=1; 58 for(int i=2;i<=n;i++) 59 { 60 if(d[i].val==d[i-1].val) 61 p[d[i].pos]=num; 62 else 63 p[d[i].pos]=++num; 64 } 65 ll ans=0; 66 for(int i=1;i<=n;i++) 67 { 68 ADD(p[i],1); 69 ans+=i-Getsum(p[i]); 70 /*Getsum求的是在插入这个值的时候自己的前面已经插了几个值, 71 按输入顺序插入的,大小是经过离散的; 72 到目前一共插了i个数,插到他前面的是顺序比他靠前,值比他小的, 73 后面的是顺序比他小但是值比他大的,也就和他构成逆序数对的数;*/ 74 } 75 printf("%lld\n",ans); 76 77 } 78 79 return 0; 80 }