bzoj3744: Gty的妹子序列 (BIT && 分块)

强制在线的区间询问逆序对数

如果不是强制在线

就是可以用莫队乱搞啦

强制在线的话

用f[i][j]记录第i块到第j个点之间的逆序对数

用s[i][j]记录前i块中小于等于j的数字个数

离散化一下

BIT用来处理需要暴力的地方即可

下面是代码

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cmath>
 4 #include <cstring>
 5 using namespace std;
 6 #define isdigit(x) (x <= '9' && x >= '0')
 7 #define lowbit(x) (x & (-x))
 8 const int N = 5e4 + 5;
 9 const int M = 300;
10 
11 struct s {
12     int u, v;
13     inline bool operator < (const s &o) const {
14         return u < o.u;
15     }
16 } a[N];
17 
18 inline void read(int &ans) {
19     ans = 0;  
20     static char buf = getchar();
21     for (; !isdigit(buf); buf = getchar());
22     for (; isdigit(buf); buf = getchar())
23         ans = ans * 10 + buf - '0';
24 }
25 
26 int n, cnt, maxn, sz;
27 int s[M][N], f[M][N], c[N], d[N], b[N];
28 
29 inline void add(int x, int a) {
30     while (x <= maxn) {
31         c[x] += a;
32         x += lowbit(x);
33     }
34 }
35 
36 inline int query(int x) {
37     int ans = 0;
38     while (x > 0) {
39         ans += c[x];
40         x -= lowbit(x);
41     }
42     return ans;
43 }
44 
45 inline void work(int x) {
46     int h = (x - 1) * sz + 1;
47     int t = x * sz;
48     for (int i = h; i <= n; i++)
49         add(d[i], 1), f[x][i] = f[x][i - 1] + i - h + 1 - query(d[i]);
50     memset(c, 0, sizeof(c));
51     for (int i = h; i <= t; i++)    s[x][d[i]]++;
52     for (int i = 1; i <= maxn; i++)    s[x][i] += s[x][i - 1];
53     for (int i = 1; i <= maxn; i++)    s[x][i] += s[x - 1][i];
54 }
55 
56 int main() {
57     read(n);
58     sz = sqrt(n);
59     for (int i = 1; i <= n; i++) {
60         read(a[i].u); a[i].v = i;
61         b[i] = (i - 1) / sz + 1;
62     }
63     cnt = b[n];
64     sort(a + 1, a + n + 1);
65     int last = 1; d[a[1].v] = 1;
66     for (int i = 2; i <= n; i++) {
67         if (a[i].u == a[i - 1].u)    d[a[i].v] = last;
68         else    d[a[i].v] = ++last;
69     } 
70     maxn = last;
71     for (int i = 1; i <= cnt; i++)
72         work(i);
73     int m; read(m);
74     int ans = 0;
75     while (m--) {
76         int l, r;
77         read(l); read(r);
78         l = l ^ ans; r = r ^ ans;
79         ans = 0;
80         if (l > r)    swap(l, r);
81         if (b[l] == b[r]) {
82             for (int i = l; i <= r; i++)
83                 add(d[i], 1), ans += i - l + 1 - query(d[i]);
84             for (int i = l; i <= r; i++)    add(d[i], -1);
85         }
86         else {
87             ans = f[b[l] + 1][r];
88             for (int i = (b[r] - 1) * sz + 1; i <= r; i++)    add(d[i], 1);
89             for (int i = b[l] * sz; i >= l; i--)
90                 add(d[i], 1), ans += query(d[i] - 1) + s[b[r] - 1][d[i] - 1] - s[b[l]][d[i] - 1];
91             for (int i = (b[r] - 1) * sz + 1; i <= r; i++)    add(d[i], -1);
92             for (int i = l; i <= b[l] * sz; i++)    add(d[i], -1);
93         }
94         printf("%d\n", ans);
95     }
96 }

 

posted @ 2018-03-15 01:05  cminus  阅读(128)  评论(0编辑  收藏  举报