求逆序对(树状数组)

洛谷传送门

虽然可以用归并排序求,但我实在记不住归并排序的代码。

还是树状数组和蔼点。

先离散化,树状数组就可以开小点,不过耗的时间多点。

——代码

 1 #include <cstdio>
 2 #include <algorithm>
 3 #define lowbit(x) x & -x
 4 
 5 using namespace std;
 6 
 7 int n, ans, sz;
 8 int a[40001], b[40001], c[160000];
 9 
10 inline void add(int x)
11 {
12     while(x <= n)
13     {
14         c[x] += 1;
15         x += lowbit(x);
16     }
17 }
18 
19 inline int sum(int x)
20 {
21     int tot = 0;
22     while(x)
23     {
24         tot += c[x];
25         x -= lowbit(x);
26     }
27     return tot;
28 }
29 
30 int main()
31 {
32     int i, k;
33     scanf("%d", &n);
34     for(i = 1; i <= n; i++) scanf("%d", &a[i]), b[i] = a[i];
35     sort(b + 1, b + n + 1);
36     sz = unique(b + 1, b + n + 1) - (b + 1);
37     for(i = n; i >= 1; i--)
38     {
39         k = lower_bound(b + 1, b + n + 1, a[i]) - b;
40         ans += sum(k);
41         add(k);
42     }
43     printf("%d", ans);
44     return 0;
45 }
View Code

 

posted @ 2017-04-21 14:35  zht467  阅读(119)  评论(0编辑  收藏  举报