Sherlock and Inversions CodeChef - IITI15
After a long series of jobless days, Sherlock and Watson frustated by the lack of new cases, decide to turn their minds toward something interesting like solving few logical problems. One of the problems they have to solve now is as follows:
Given an array A of size N and a list of Q number of queries, where each query has two numbers L and R, find for each query the number of inversions in the subarray from Lth to Rth position (both inclusive) of the array A( array has 1-based index).
For an array A two elements A[i] and A[j] form an inversion if A[i] > A[j] and i < j. Help them to solve this problem.
Input
- First line contains a single integer, length N of the array.
- Second line has N space separated numbers, where ith element is A[i].
- Third line has a single integer Q.
- Next Q lines have 2 space separated integers L and R of that query.
Output
- Output Q lines, ith line having a single integer, the answer to the ith query
Constraints
- 1 ≤ N ≤ 20000
- 0 ≤ A[i] ≤ 10^9
- 1 ≤ Q ≤ 20000
- 1 ≤ L ≤ R ≤ N
题解:莫队+树状数组,找每个区间的逆序对(i<j,a[i]>a[j]),用树状数组统计就行(BZOJ 3298,同一种做法)。
感受:每个元素对区间的贡献还没想明白!!!
懂了一点点,每个数的贡献是相对于原来的状态,即上一个ans而言,这里,加入一个数或者减少一个数,原来的逆序对会变化。
- 每次在最后添加一个数,比这个数大的数都会与其形成一个逆序对
- 每次在最后移除一个数,比这个数大的数都会与其形成一个逆序对
- 每次在最前添加一个数,比这个数小的数都会与其减少一个逆序对
- 每次在最前移除一个数,比这个数小的数都会与其减少一个逆序对 ------------摘自https://www.cnblogs.com/zcysky/p/6847290.html
1 #pragma warning(disable:4996) 2 #include<cmath> 3 #include<map> 4 #include<cstdio> 5 #include<cstring> 6 #include<iostream> 7 #include<algorithm> 8 using namespace std; 9 10 const int maxn = 20005; 11 12 int n, m, k, unit; 13 int a[maxn], bit[maxn], res[maxn], b[maxn]; 14 15 struct node { int l, r, id; } q[maxn]; 16 17 bool cmp(const node& a, const node& b) { 18 if (a.l / unit == b.l / unit) return a.r < b.r; 19 return a.l < b.l; 20 } 21 22 void Inite() { 23 unit = sqrt(n); 24 memset(bit, 0, sizeof(bit)); 25 } 26 27 int sum(int i) { 28 int s = 0; 29 while (i > 0) { 30 s += bit[i]; 31 i -= i & -i; 32 } 33 return s; 34 } 35 36 void add(int i, int x) { 37 while (i <= n) { 38 bit[i] += x; 39 i += i & -i; 40 } 41 } 42 43 int main() 44 { 45 while (scanf("%d", &n) != EOF) { 46 Inite(); 47 48 for (int i = 1; i <= n; i++) { 49 scanf("%d", &a[i]); 50 b[i] = a[i]; 51 } 52 53 sort(a + 1, a + n + 1); 54 k = unique(a + 1, a + n + 1) - (a + 1); 55 56 map<int, int> p; 57 for (int i = 1; i <= k; i++) if (!p[a[i]]) p[a[i]] = i; 58 59 scanf("%d", &m); 60 for (int i = 1; i <= m; i++) { 61 int u, v; 62 scanf("%d%d", &u, &v); 63 q[i].l = u; 64 q[i].r = v; 65 q[i].id = i; 66 } 67 68 sort(q + 1, q + m + 1, cmp); 69 70 int L = q[1].l, R = L - 1; 71 int ans = 0; 72 for (int i = 1; i <= m; i++) { 73 while (L < q[i].l) { 74 ans -= sum(p[b[L]] - 1); 75 add(p[b[L]], -1); 76 L++; 77 } 78 while (L > q[i].l) { 79 L--; 80 ans += sum(p[b[L]] - 1); 81 add(p[b[L]], 1); 82 } 83 while (R < q[i].r) { 84 R++; 85 ans += (R - L - sum(p[b[R]])); 86 add(p[b[R]], 1); 87 } 88 while (R > q[i].r) { 89 ans -= (R - L - sum(p[b[R]]) + 1); 90 add(p[b[R]], -1); 91 R--; 92 } 93 res[q[i].id] = ans; 94 } 95 for (int i = 1; i <= m; i++) printf("%d\n", res[i]); 96 } 97 return 0; 98 }