链接:
http://codeforces.com/contest/785/problem/E
题意:
给你一个序列,初始值a[i]=i,每次操作交换a[l]和a[r],问有多少个逆序对
题解:
分块就可以了
代码:
31 int n, q; 32 int a[MAXN]; 33 VI Block[MAXN >>1]; 34 int L[MAXN], R[MAXN], Belong[MAXN]; 35 36 void init() { 37 int cap = sqrt(n); 38 int num = n / cap; 39 if (n%cap != 0) num++; 40 rep(i, 1, num + 1) { 41 L[i] = (i - 1)*cap + 1; 42 R[i] = i*cap; 43 } 44 rep(i, 1, n + 1) Belong[i] = (i - 1) / cap + 1; 45 rep(i, 1, num + 1) rep(j, L[i], R[i] + 1) Block[i].pb(j); 46 } 47 48 int query(int l, int r, int x) { 49 if (l > r) return 0; 50 int res = 0; 51 if (Belong[l] == Belong[r]) { 52 rep(i, l, r + 1) if (a[i] < x) res++; 53 return res; 54 } 55 int id = Belong[l]; 56 rep(i, l, R[id] + 1) if (a[i] < x) res++; 57 rep(i, Belong[l] + 1, Belong[r]) 58 res += upper_bound(all(Block[i]), x) - Block[i].begin(); 59 id = Belong[r]; 60 rep(i, L[id], r + 1) if (a[i] < x) res++; 61 return res; 62 } 63 64 void update(int l, int r) { 65 int x = a[l], y = a[r]; 66 int id = Belong[l]; 67 Block[id].erase(lower_bound(all(Block[id]), x)); 68 Block[id].insert(lower_bound(all(Block[id]), y), y); 69 id = Belong[r]; 70 Block[id].erase(lower_bound(all(Block[id]), y)); 71 Block[id].insert(lower_bound(all(Block[id]), x), x); 72 swap(a[l], a[r]); 73 } 74 75 int main() { 76 ios::sync_with_stdio(false), cin.tie(0); 77 cin >> n >> q; 78 init(); 79 rep(i, 1, n + 1) a[i] = i; 80 ll ans = 0; 81 while (q--) { 82 int l, r; 83 cin >> l >> r; 84 if (l == r) { 85 cout << ans << endl; 86 continue; 87 } 88 if (l > r) swap(l, r); 89 int t1 = query(l + 1, r - 1, a[l]); 90 int t2 = (r - 1 - l - 1 + 1) - t1; 91 ans -= t1; 92 ans += t2; 93 t1 = query(l + 1, r - 1, a[r]); 94 t2 = (r - 1 - l - 1 + 1) - t1; 95 ans += t1; 96 ans -= t2; 97 if (a[l] < a[r]) ans++; 98 else ans--; 99 cout << ans << endl; 100 update(l, r); 101 } 102 return 0; 103 }