树状数组模板3——求逆序对

树状数组的模板,通过其性质,寻找i<j但a[i]>a[j]的个数,此处添加了离散化来优化时间,减小常数

 1 #include<cstdio>
 2 #include<cctype>
 3 #include<algorithm>
 4 using namespace std;
 5  
 6 int c[100010],n,tot,b[100010];
 7 long long ans;
 8 struct node
 9 {
10     int x,val;
11     bool operator <(const node &k)const{
12         return val<k.val;
13     }
14 }a[100010];
15  
16 int read()
17 {
18     int x=0,f=1;
19     char c=getchar();
20     while (!isdigit(c))
21         f=c=='-'?-1:1,c=getchar();
22     while (isdigit(c))
23         x=(x<<1)+(x<<3)+(c^48),c=getchar();
24     return x*f;
25 }
26  
27 int lowbit(int x)
28 {
29     return x&-x;
30 }
31  
32 int query(int x)
33 {
34     int tot=0;
35     for (int i=x;i;i-=lowbit(i))
36         tot+=c[i];
37     return tot;
38 }
39  
40 void update(int x,int val)
41 {
42     for (int i=x;i<=n;i+=lowbit(i))
43         c[i]+=val;
44 }
45  
46 int main()
47 {
48     int i,j;
49     n=read();
50     for (i=1;i<=n;i++)
51     {
52         a[i].x=i;
53         a[i].val=read();
54     }
55     sort(a+1,a+n+1);
56     for (i=1;i<=n;i++)
57     {
58         if (i==1||a[i].val!=a[i-1].val)
59             tot++;
60         b[a[i].x]=tot;
61     }
62     for (i=1;i<=n;i++)
63     {
64         ans+=i-1-query(b[i]);
65         update(b[i],1);
66     }
67     printf("%lld",ans);
68     return 0;
69 }
原文地址:https://www.cnblogs.com/Ronald-MOK1426/p/8848908.html