树状数组求逆序对

树状数组求逆序对。(二进制真好玩)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/* problem :P1908 逆序对
* 用树状数组来求逆序对,思想很奇妙,很受益,对树状数组的理解又加深了一些。
*
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int tree[500010],rank[500010],n;
long long ans;
struct point
{
int num,val;
}a[500010];
inline bool cmp(point q,point w)
{
if(q.val==w.val)
return q.num<w.num;
return q.val<w.val;
}
inline void insert(int p,int d)
{
for(;p<=n;p+=p&-p)
tree[p]+=d;
}
inline int query(int p)
{
int sum=0;
for(;p;p-=p&-p)
sum+=tree[p];
return sum;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i].val),a[i].num=i;
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++)
rank[a[i].num]=i;
for(int i=1;i<=n;i++)
{
insert(rank[i],1);
ans+=i-query(rank[i]);
}
printf("%lld",ans);
return 0;
}