SGU180(树状数组,逆序对,离散)

Inversions

time limit per test: 0.25 sec. 
memory limit per test: 4096 KB
input: standard 
output: standard




There are N integers (1<=N<=65537) A1, A2,.. AN (0<=Ai<=10^9). You need to find amount of such pairs (i, j) that 1<=i<j<=N and A[i]>A[j].

Input
The first line of the input contains the number N. The second line contains N numbers A1...AN.

Output
Write amount of such pairs.

Sample test(s)

Input
 
 

2 3 1 5 4
 
 

Output
 
 
3

 

这道题需要离散,树状数组求逆序对是离散后,统计加入该元素时当前数组中

已经存在多少个比它大的数,这就是该数作为逆序对后者的贡献度,然后就可以

求解了,一般需要离散化。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<iostream>
 6 #define N 70007
 7 using namespace std;
 8 
 9 int n;
10 long long ans;
11 int b[N],c[N];
12 struct Node
13 {
14     int zhi,id;
15 }a[N];
16 
17 bool cmp(Node x,Node y)
18 {
19     return x.zhi<y.zhi;
20 }
21 int lowbit(int x)
22 {
23     return x&(-x);
24 }
25 void change(int x,int y)
26 {
27     for (int i=x;i<=n;i+=lowbit(i))
28         c[i]+=y;
29 }
30 int query(int x)
31 {
32     int res=0;
33     for (int i=x;i>=1;i-=lowbit(i))
34         res+=c[i];
35     return res;    
36 }
37 int main()
38 {
39     scanf("%d",&n);
40     for (int i=1;i<=n;i++)
41     {
42         scanf("%d",&a[i].zhi);
43         a[i].id=i;    
44     }
45     sort(a+1,a+n+1,cmp);
46     int cnt=0;
47     for (int i=1;i<=n;i++)
48     {
49         if (a[i].zhi!=a[i-1].zhi) b[a[i].id]=++cnt;
50         else b[a[i].id]=cnt;
51     }
52     for (int i=1;i<=n;i++)
53     {
54         change(b[i],1);
55         ans=ans+query(n)-query(b[i]);    
56     }
57     printf("%lld",ans);
58 }
 
 
 
原文地址:https://www.cnblogs.com/fengzhiyuan/p/7574333.html