树状数组求逆序对

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int maxn=500500;
 8 int n;
 9 int aa[maxn];//离散后
10 int c[maxn];//树状数组
11 
12 struct Node
13 {
14     int v;
15     int order;
16 } in[maxn];
17 
18 int lowbit(int x)
19 {
20     return x&(-x);
21 }
22 
23 void update(int t,int value)//在t单点更新value 
24 {
25     int i;
26     for(i=t;i<=n;i+=lowbit(i))
27     {
28         c[i]+=value;
29     }
30 }
31 
32 int getsum(int x)
33 {
34     int i;
35     int temp=0;
36     for(i=x;i>=1;i-=lowbit(i))
37     {
38         temp+=c[i];
39     }
40     return temp;
41 }
42 
43 bool cmp(Node a,Node b)
44 {
45     return a.v<b.v;
46 }
47 
48 int main()
49 {
50     int i,j;
51     while(scanf("%d",&n)==1&&n)
52     {
53         //以防数据太大,先离散化,离散其实就是看in[i].v排第几位 
54         for(i=1;i<=n;i++)
55         {
56             scanf("%d",&in[i].v);
57             in[i].order=i;
58         } 
59         
60         sort(in+1,in+n+1,cmp);
61         for(i=1;i<=n;i++)
62         aa[in[i].order]=i;//原来in中下标为in[i].order排在第i位(因为排序了),对应的值就是i 
63         memset(c,0,sizeof(c));
64         long long ans=0;
65         for(i=1;i<=n;i++)
66         {
67             update(aa[i],1);//在aa[i]位置更新值1 
68             ans+=i-getsum(aa[i]);
69         }
70         cout<<ans<<endl;        
71     }
72     return 0;
73 }

 

posted @ 2017-10-19 11:46  东流vip  阅读(150)  评论(0编辑  收藏  举报