bzoj 3289: Mato的文件管理 莫队+线段树
给一些询问,每个询问给出区间[L, R] , 求这段区间的逆序数。
先分块排序, 然后对于每次更改, 如果是更改L, 那么应该查询区间内比他小的数的个数, 如果更改R, 查区间内比他大的数的个数。
记得离散化。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define pb(x) push_back(x) 4 #define ll long long 5 #define mk(x, y) make_pair(x, y) 6 #define lson l, m, rt<<1 7 #define mem(a) memset(a, 0, sizeof(a)) 8 #define rson m+1, r, rt<<1|1 9 #define mem1(a) memset(a, -1, sizeof(a)) 10 #define mem2(a) memset(a, 0x3f, sizeof(a)) 11 #define rep(i, a, n) for(int i = a; i<n; i++) 12 #define ull unsigned long long 13 typedef pair<int, int> pll; 14 const double PI = acos(-1.0); 15 const double eps = 1e-8; 16 const int mod = 1e9+7; 17 const int inf = 1061109567; 18 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; 19 const int maxn = 50005; 20 int a[maxn], ans[maxn], sum[maxn<<2], b[maxn]; 21 void pushUp(int rt) { 22 sum[rt] = sum[rt<<1]+sum[rt<<1|1]; 23 } 24 void update(int p, int l, int r, int rt, int val) { 25 if(l == r) { 26 sum[rt]+=val; 27 return ; 28 } 29 int m = l+r>>1; 30 if(p<=m) 31 update(p, lson, val); 32 else 33 update(p, rson, val); 34 pushUp(rt); 35 } 36 int query(int L, int R, int l, int r, int rt) { 37 if(R<L) 38 return 0; 39 if(L<=l&&R>=r) { 40 return sum[rt]; 41 } 42 int m = l+r>>1, ret = 0; 43 if(L<=m) 44 ret += query(L, R, lson); 45 if(R>m) 46 ret += query(L, R, rson); 47 return ret; 48 } 49 struct node 50 { 51 int block, r, l, id; 52 bool operator < (node a)const 53 { 54 if(block == a.block) 55 return r<a.r; 56 return block<a.block; 57 } 58 }q[maxn]; 59 int main() 60 { 61 int n, m; 62 while(~scanf("%d", &n)) { 63 for(int i = 1; i<=n; i++) { 64 scanf("%d", &a[i]); 65 b[i-1] = a[i]; 66 } 67 sort(b, b+n); 68 int cnt = unique(b, b+n)-b; 69 for(int i = 1; i<=n; i++) 70 a[i] = lower_bound(b, b+cnt, a[i])-b+1; 71 scanf("%d", &m); 72 int BLOCK = sqrt(n*1.0); 73 for(int i = 0; i<m; i++) { 74 scanf("%d%d", &q[i].l, &q[i].r); 75 q[i].id = i; 76 q[i].block = q[i].l/BLOCK; 77 } 78 mem(sum); 79 sort(q, q+m); 80 int tmp = 0; 81 for(int i = q[0].l; i<=q[0].r; i++) { 82 tmp += query(a[i]+1, n, 1, n, 1); 83 update(a[i], 1, n, 1, 1); 84 } 85 ans[q[0].id] = tmp; 86 for(int i = 1; i<m; i++) { 87 for(int j = q[i-1].l; j<q[i].l; j++) { 88 update(a[j], 1, n, 1, -1); 89 tmp -= query(1, a[j]-1, 1, n, 1); 90 } 91 for(int j = q[i-1].l-1; j>=q[i].l; j--) { 92 tmp += query(1, a[j]-1, 1, n, 1); 93 update(a[j], 1, n, 1, 1); 94 } 95 for(int j = q[i-1].r+1; j<=q[i].r; j++) { 96 tmp += query(a[j]+1, n, 1, n, 1); 97 update(a[j], 1, n, 1, 1); 98 } 99 for(int j = q[i-1].r; j>q[i].r; j--) { 100 update(a[j], 1, n, 1, -1); 101 tmp -= query(a[j]+1, n, 1, n, 1); 102 } 103 ans[q[i].id] = tmp; 104 } 105 for(int i = 0; i<m; i++) { 106 printf("%d\n", ans[i]); 107 } 108 } 109 return 0; 110 }