求逆序对(树状数组)
虽然可以用归并排序求,但我实在记不住归并排序的代码。
还是树状数组和蔼点。
先离散化,树状数组就可以开小点,不过耗的时间多点。
——代码
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 }