zoukankan      html  css  js  c++  java
  • 可持久化字典树

    #include<cstdio>
    #include<vector>
    #include<algorithm>
    #include<cstring>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ull unsigned long long
    
    using namespace std;
    
    const int N = 5e4 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1000000007;
    const double eps = 1e-6;
    const double PI = acos(-1);
    
    int n, q, a[N];
    char op[10];
    
    namespace Trie {
        int to[32][2], Rt[N], tot;
        int ch[N * 32][2], cnt[N * 32];
        void init() {
            tot = 0;
            for(int i = 0; i <= 30; i++)
                to[i][0] = 0, to[i][1] = 1;
        }
        inline void cpy(int x, int y) {
            ch[x][0] = ch[y][0];
            ch[x][1] = ch[y][1];
            cnt[x] = cnt[y];
        }
        void Insert(int v, int x, int y) {
            cpy(x, y);
            for(int i = 30; i >= 0; i--) {
                if(v >> i & 1 || to[i][0] == to[i][1]) {
                    ch[x][1] = ++tot;
                    x = ch[x][1]; y = ch[y][1];
                    cpy(x, y);
                } else {
                    ch[x][0] = ++tot;
                    x = ch[x][0]; y = ch[y][0];
                    cpy(x, y);
                }
                cnt[x]++;
            }
        }
        void Rebuild(int *a, int n) {
            tot = 0;
            for(int i = 1; i <= n; i++) {
                Rt[i] = ++tot;
                Insert(a[i], Rt[i], Rt[i - 1]);
            }
        }
        int Query(int L, int R, int K) {
            int ans = 0, x = Rt[R], y = Rt[L - 1];
            for(int i = 30; i >= 0; i--) {
                bool op = !(to[i][0] < to[i][1]);
                if(cnt[ch[x][op]] - cnt[ch[y][op]] >= K) {
                    ans += to[i][op] << i;
                    x = ch[x][op]; y = ch[y][op];
                } else {
                    K -= cnt[ch[x][op]] - cnt[ch[y][op]];
                    ans += to[i][!op] << i;
                    x = ch[x][!op]; y = ch[y][!op];
                }
            }
            return ans;
        }
        void Or(int x) {
            bool need = false;
            for(int i = 0; i <= 30; i++) {
                if(x >> i & 1) {
                    if(to[i][0] ^ to[i][1]) need = true;
                    to[i][0] = to[i][1] = 1;
                }
            }
            if(need) Rebuild(a, n);
        }
        void And(int x) {
            bool need = false;
            for(int i = 0; i <= 30; i++) {
                if(!(x >> i & 1)) {
                    if(to[i][0] ^ to[i][1]) need = true;
                    to[i][0] = to[i][1] = 0;
                }
            }
            if(need) Rebuild(a, n);
        }
        void Xor(int x) {
            for(int i = 0; i <= 30; i++)
                if(x >> i & 1) to[i][0] ^= 1, to[i][1] ^= 1;
        }
    }
    
    int main() {
    //    freopen("text.in", "r", stdin);
        scanf("%d%d", &n, &q);
        for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
        Trie::init();
        Trie::Rebuild(a, n);
        while(q--) {
            scanf("%s", op);
            if(op[0] == 'O') {
                int x; scanf("%d", &x);
                Trie::Or(x);
            } else if(op[0] == 'A' && op[1] == 'n') {
                int x; scanf("%d", &x);
                Trie::And(x);
            } else if(op[0] == 'X') {
                int x; scanf("%d", &x);
                Trie::Xor(x);
            } else {
                int L, R, K;
                scanf("%d%d%d", &L, &R, &K);
                printf("%d
    ", Trie::Query(L, R, K));
            }
        }
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    【SQL】在含有GROUP BY的SELECT语句中如何显示COUNT()为0的结果
    【SQL】SQL分页查询总结
    开篇
    Android Native Crash 排查思路
    jmeter+ant+jenkins接口自动化测试框架
    为何推荐使用线程池而不是显式创建线程原因之一—至少让线程有范围和限制
    quartz 中的线程池
    select in 查询结果无顺序及解决办法
    Druid 数据库连接池如何根据url加载Driver
    java 线程池参数
  • 原文地址:https://www.cnblogs.com/CJLHY/p/10559339.html
Copyright © 2011-2022 走看看