扩大
缩小

BZOJ4103 异或运算

4103: [Thu Summer Camp 2015]异或运算

Time Limit: 20 Sec  Memory Limit: 512 MB

Description

给定长度为n的数列X={x1,x2,...,xn}和长度为m的数列Y={y1,y2,...,ym},令矩阵A中第i行第j列的值Aij=xi xor  yj,每次询问给定矩形区域i∈[u,d],j∈[l,r],找出第k大的Aij。

Input

第一行包含两个正整数n,m,分别表示两个数列的长度

第二行包含n个非负整数xi
第三行包含m个非负整数yj
第四行包含一个正整数p,表示询问次数
随后p行,每行均包含5个正整数,用来描述一次询问,每行包含五个正整数u,d,l,r,k,含义如题意所述。

Output

共p行,每行包含一个非负整数,表示此次询问的答案。

Sample Input

3 3
1 2 4
7 6 5
3
1 2 1 2 2
1 2 1 3 4
2 3 2 3 4

Sample Output

6
5
1

HINT

对于100%的数据,0<=Xi,Yj<2^31,

1<=u<=d<=n<=1000,
1<=l<=r<=m<=300000,
1<=k<=(d-u+1)*(r-l+1),
1<=p<=500
对n暴力,m建可持久化Trie
BZOJ+1,您的最佳选择
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 template <class _T> inline void read(_T &_x) {
 4     int _t; bool flag = false;
 5     while ((_t = getchar()) != '-' && (_t < '0' || _t > '9')) ;
 6     if (_t == '-') _t = getchar(), flag = true; _x = _t - '0';
 7     while ((_t = getchar()) >= '0' && _t <= '9') _x = _x * 10 + _t - '0';
 8     if (flag) _x = -_x;
 9 }
10 typedef long long LL;
11 const int maxn = 1010;
12 const int maxm = 300010;
13 const int DEP = 30;
14 struct Trie {
15     int v, ch[2];
16 }t[maxm * 32];
17 int n, m, p, cnt;
18 int root[maxm], X[maxn], Y[maxm];
19 int Query(int u, int d, int l, int r, int K) {
20     static int lr[maxn], rr[maxn];
21     for (int i = u; i <= d; ++i)
22         lr[i] = root[l - 1], rr[i] = root[r];
23     int res = 0, tot;
24     for (int i = DEP; i >= 0; --i) {
25         tot = 0;
26         for (int j = u, x; j <= d; ++j) {
27             x = ((X[j] >> i) & 1) ^ 1;
28             tot += t[t[rr[j]].ch[x]].v - t[t[lr[j]].ch[x]].v;
29         }
30         if (tot >= K) {
31             for (int j = u, x; j <= d; ++j) {
32                 x = ((X[j] >> i) & 1) ^ 1;
33                 rr[j] = t[rr[j]].ch[x];
34                 lr[j] = t[lr[j]].ch[x];
35             }
36             res += 1 << i;
37         } else {
38             for (int j = u, x; j <= d; ++j) {
39                 x = ((X[j] >> i) & 1);
40                 rr[j] = t[rr[j]].ch[x];
41                 lr[j] = t[lr[j]].ch[x];
42             }
43             K -= tot;
44         }
45     }
46     return res;
47 }
48 void update(int r1, int &r2, int v, int dep) {
49     t[r2 = ++cnt] = t[r1], ++t[r2].v;
50     if (dep < 0) return ;
51     update(t[r1].ch[(v >> dep) & 1], t[r2].ch[(v >> dep) & 1], v, dep - 1);
52 }
53 int main() {
54     //freopen("4103.in", "r", stdin);
55     //freopen("4103.out", "w", stdout);
56     read(n), read(m);
57     for (int i = 1; i <= n; ++i) read(X[i]);
58     for (int i = 1; i <= m; ++i)
59         read(Y[i]), update(root[i - 1], root[i], Y[i], DEP);
60     read(p);
61     for (int i = 1, u, d, l, r, k; i <= p; ++i) {
62         read(u), read(d), read(l), read(r), read(k);
63         printf("%d\n", Query(u, d, l, r, k));
64     }
65     return 0;
66 }
View Code

 

posted @ 2017-05-15 21:59  HPLV  阅读(174)  评论(0编辑  收藏  举报