一个上午两道题,妥妥的作死。。。

首先还是按照之前思路建立可持久化trie,然后发现了点问题。。。

trie只能支持对于给定v求出最大xor值,也就是说我们要枚举a[i] (i ∈ [l, r]),于是单次询问复杂度O(n * 30),爆表

于是想到了需要预处理,方法是分块,预处理复杂度O(n * (n / sz) * 30),单次询问复杂度O(sz * 30)(sz为块的大小)

到这里的时候。。。网上的题解君们就只剩下程序了。。。于是害得蒟蒻理解错惹%>_<%

于是看到了BLADEVIL的题解,简直一目了然(但是程序注释不删不敢恭维= =)

重点要注意的就两个地方:

(1)f[i][j]为从第i个块的第一个元素开始,到第j个数的区间中,任意找两个数的xor值最大

(2)在计算l和r的时候。。。会爆int

 

  1 /**************************************************************
  2     Problem: 2741
  3     User: rausen
  4     Language: C++
  5     Result: Accepted
  6     Time:5768 ms
  7     Memory:11508 kb
  8 ****************************************************************/
  9  
 10 #include <cstdio>
 11 #include <cmath>
 12 #include <algorithm>
 13  
 14 using namespace std;
 15 typedef long long ll;
 16 const int N = 12005;
 17 const int sqrt_N = 120;
 18  
 19 struct trie_node {
 20     int son[2], cnt;
 21 } t[N * 35];
 22 int cnt_trie = 1;
 23  
 24 int n, m, a[N];
 25 int root[N], sz, w[N];
 26 int f[sqrt_N][N];
 27  
 28 inline int read() {
 29     int x = 0;
 30     char ch = getchar();
 31     while (ch < '0' || '9' < ch)
 32         ch = getchar();
 33     while ('0' <= ch && ch <= '9') {
 34         x = x * 10 + ch - '0';
 35         ch = getchar();
 36     }
 37     return x;
 38 }
 39  
 40 int A[35];
 41 void insert(int &root, int v) {
 42     int R = root, now = ++cnt_trie, i;
 43     root = now;
 44     for (i = 0; i <= 30; ++i)
 45         A[i] = v & 1, v >>= 1;
 46     reverse(A, A + 31);
 47     for (i = 0; i <= 30; ++i) {
 48         t[now].son[0] = t[R].son[0], t[now].son[1] = t[R].son[1];
 49         R = t[R].son[A[i]], now = t[now].son[A[i]] = ++cnt_trie;
 50         t[now].cnt = t[R].cnt + 1;
 51     }
 52 }
 53  
 54 int query(int x, int y, int v) {
 55     int i, res = 0;
 56     for (i = 0; i <= 30; ++i)
 57         A[i] = v & 1, v >>= 1;
 58     reverse(A, A + 31);
 59     for (i = 0; i <= 30; ++i) {
 60         if (t[t[y].son[!A[i]]].cnt - t[t[x].son[!A[i]]].cnt)
 61             x = t[x].son[!A[i]], y = t[y].son[!A[i]], res += (1 << 30 - i);
 62         else x = t[x].son[A[i]], y = t[y].son[A[i]];
 63     }
 64     return res;
 65 }
 66  
 67 int Query(int l, int r) {
 68     int i, maxi, res = w[l] < w[r] ? f[w[l] + 1][r] : 0;
 69     for (i = min(w[l] * sz, r); i >= l; --i)
 70         res = max(res, query(root[l - 1], root[r], a[i]));
 71     return res;
 72 }
 73  
 74 void Block() {
 75     int i, j, l;
 76     sz = (int) sqrt(n);
 77     for (i = 1; i <= n; ++i) {
 78         w[i] = (int) (i - 1) / sz + 1;
 79         for (j = 1; j <= w[i]; ++j) {
 80             l = (j - 1) * sz;
 81             f[j][i] = max(f[j][i - 1], query(root[l], root[i], a[i]));
 82         }
 83     }
 84 }
 85  
 86 int main() {
 87     int i, x, y, l, r, last_ans = 0;
 88     n = read(), m = read();
 89     for (i = 1, a[0] = root[0] = 0; i <= n; ++i) {
 90         a[i] = a[i - 1] ^ read(), root[i] = root[i - 1];
 91         insert(root[i], a[i]);
 92     }
 93     Block();
 94     while (m--) {
 95         x = read(), y = read();
 96         l = min(((ll) x + last_ans) % n + 1, ((ll) y + last_ans) % n + 1);
 97         r = max(((ll) x + last_ans) % n + 1, ((ll) y + last_ans) % n + 1);
 98         printf("%d\n", last_ans = Query(l - 1, r));
 99     }
100     return 0;
101 }
View Code

 

By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
posted on 2014-12-21 12:24  Xs酱~  阅读(571)  评论(0编辑  收藏  举报