CF 540E, 树状数组
Posted 茶杯
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF 540E, 树状数组相关的知识,希望对你有一定的参考价值。
题目大意:在1~10^9的范围内随便交换某些位置上的数,求逆序对数量,交换位置<=10^5
解:因为是交换位置很少,离散化来做,逆序对可以看成两部分,一部分是出现位置的逆序对,另一部分的出现了的数对于没有交换位置上的数(没有在离散化中出现的数)的逆序对。分别统计一下,第一part用树状数组,第二part之间算一下区间实际的数字和有多少个交换了位置的数字即可。
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <utility> 5 #include <map> 6 #include <string> 7 #include <cmath> 8 #include <vector> 9 #include <cstring> 10 11 using namespace std; 12 13 #define SQR(x) ((x)*(x)) 14 #define LL long long 15 #define LOWBIT(x) ((x)&(-(x))) 16 #define PB push_back 17 #define MP make_pair 18 19 #define MAXN 211111 20 21 struct TreeArray{ 22 int tree[MAXN], n; 23 void clear(int nn = MAXN - 10) { 24 n = nn; 25 memset(tree, 0, sizeof(tree[0]) * (n + 10)); 26 } 27 void add(int x, int num = 1) { 28 while (x <= n) { 29 tree[x] += num; 30 x += LOWBIT(x); 31 } 32 } 33 int get(int x) { 34 int res = 0; 35 while (x > 0) { 36 res += tree[x]; 37 x -= LOWBIT(x); 38 } 39 return res; 40 } 41 } TA; 42 43 pair<int, int > query[MAXN]; 44 vector <int > lsh; 45 vector <int > a; 46 int n; 47 LL ans; 48 49 void init() { 50 cin >> n; 51 int x, y; 52 lsh.clear(); 53 for (int i = 0; i < n; ++i) { 54 cin >> x >> y; 55 query[i] = MP(x, y); 56 lsh.PB(x); lsh.PB(y); 57 } 58 sort(lsh.begin(), lsh.end()); 59 lsh.erase(unique(lsh.begin(), lsh.end()), lsh.end()); 60 } 61 62 #define INDEX(x) ((lower_bound(lsh.begin(), lsh.end(), (x))-lsh.begin())+1) 63 64 void solve() { 65 ans = 0; 66 a = lsh; 67 TA.clear(lsh.size()+10); 68 for (int i = 0; i < n; ++i) { 69 // cout << query[i].first <<‘ ‘<< query[i].second << endl; 70 swap(a[INDEX(query[i].first)-1], a[INDEX(query[i].second)-1]); 71 } 72 73 // for (int i = 0; i < lsh.size(); ++i) cout << lsh[i] <<‘ ‘; cout << endl; 74 // for (int i = 0; i < a.size(); ++i) cout << a[i] <<‘ ‘; cout << endl; 75 76 for (int i = (int)a.size() - 1; i >= 0; --i) { 77 ans += TA.get(INDEX(a[i]) - 1); 78 TA.add(INDEX(a[i])); 79 int key = 0, t; 80 t = INDEX(a[i]) - 1; 81 if (i < t) { 82 key = (lsh[t] - lsh[i] - 1) - (t - i - 1); 83 } 84 else { 85 key = (lsh[i] - lsh[t] - 1) - (i - t - 1); 86 } 87 ans += key; 88 // cout << ans << endl; 89 } 90 } 91 92 int main() { 93 // freopen("test.txt", "r", stdin); 94 ios::sync_with_stdio(false); 95 init(); 96 solve(); 97 cout << ans << endl; 98 return 0; 99 }
以上是关于CF 540E, 树状数组的主要内容,如果未能解决你的问题,请参考以下文章
[CF369E]Valera and Queries_离线_树状数组
CF749E Inversions After Shuffle 解题报告 (期望 树状数组)
Codeforces Round #301 (Div. 2) E. Infinite Inversions —— 逆序对 离散化 + 树状数组