返回顶部

模板 - 可持久化Trie

https://www.acwing.com/problem/content/258/

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N = 600010;
int trie[N * 24][2], latest[N * 24];
int s[N], root[N], n, m, tot;

void Insert(int i, int k, int p, int q) {
    if(k < 0) {
        latest[q] = i;
        return;
    }
    int c = s[i] >> k & 1;
    if(p)
        trie[q][c ^ 1] = trie[p][c ^ 1];
    trie[q][c] = ++tot;
    Insert(i, k - 1, trie[p][c], trie[q][c]);
    latest[q] = max(latest[trie[q][0]], latest[trie[q][1]]);
}

int Query(int now, int val, int k, int limit) {
    if(k < 0)
        return s[latest[now]] ^ val;
    int c = val >> k & 1;
    if(latest[trie[now][c ^ 1]] >= limit)
        return Query(trie[now][c ^ 1], val, k - 1, limit);
    else
        return Query(trie[now][c], val, k - 1, limit);
}

int main() {
#ifdef Yinku
    freopen("Yinku.in", "r", stdin);
#endif // Yinku
    int n, m;
    scanf("%d%d", &n, &m);
    latest[0] = -1;
    root[0] = ++tot;
    Insert(0, 23, 0, root[0]);
    for(int i = 1; i <= n; ++i) {
        int x;
        scanf("%d", &x);
        s[i] = s[i - 1] ^ x;
        root[i] = ++tot;
        Insert(i, 23, root[i - 1], root[i]);
    }
    for(int i = 1; i <= m; ++i) {
        char op[2];
        scanf("%s", op);
        if(op[0] == 'A') {
            int x;
            scanf("%d", &x);
            root[++n] = ++tot;
            s[n] = s[n - 1] ^ x;
            Insert(n, 23, root[n - 1], root[n]);
        } else {
            int l, r, x;
            scanf("%d%d%d", &l, &r, &x);
            printf("%d\n", Query(root[r - 1], x ^ s[n], 23, l - 1));
        }
    }

    return 0;
}
posted @ 2019-09-05 17:22  Inko  阅读(...)  评论(...编辑  收藏