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 }

 

posted on 2015-12-18 16:25  yohaha  阅读(245)  评论(0编辑  收藏  举报

导航