• 《算法竞赛进阶指南》0x48可持久化数据结构 可持久化Trie


    题目链接:https://www.acwing.com/problem/content/258/

    题目给出长度为n的序列,操作有两种,求[p,n]段的异或和再与x的异或,或者增加一个数x,使用可持久化Trie和异或前缀和可以解决,但是需要在[l-1,r-1]区间内,右区间自然满足,左区间的话需要加上latest标记,使得当前访问结点的版本是属于l-1或者之后的。时间复杂度为O((n+m)*32)。

    代码:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int maxn = 600010;
    int s[maxn],root[maxn],n,m,tot;
    int trie[maxn*24][2],latest[maxn*24];
    void insert(int i,int k,int p,int q){
        if(k<0){
            latest[q]=i;
            return;
        }
        int c=(s[i]>>k)&1;
        //除了当前的c分支外所有的分支都指向p的分支 
        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)
        //一定有一个子节点是满足的 ,否则不可能进入now结点 
            return query(trie[now][c^1],val,k-1,limit);
        else return query(trie[now][c],val,k-1,limit);
    }
    int main(){
        cin>>n>>m;
        latest[0]=-1;
        root[0]=++tot;//插入n+1个数,第一个是0 
        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);
                ++n;
                s[n]=s[n-1]^x;
                root[n]=++tot;
                insert(n,23,root[n-1],root[n]);
            }else{
                int l,r,x;
                scanf("%d%d%d",&l,&r,&x);
                printf("%d
    ",query(root[r-1],s[n]^x,23,l-1));
            }
        }
    }
    每一个不曾起舞的日子,都是对生命的辜负。
  • 相关阅读:
    SpringSource Tools Suite 字体偏小问题
    Ubuntu11.10 Eclipse 提示框 为黑色 解决方案
    图的广度优先搜索 皇星客栈
    哈夫曼编码 皇星客栈
    m_hWnd与this指针 皇星客栈
    建立中序线索二叉树 皇星客栈
    第一部分 整数Hash 皇星客栈
    哈夫曼树建立 皇星客栈
    Hash入门 皇星客栈
    stdin,stdout 和STDOUT_FILENO,STDIN_FILENO的学习 皇星客栈
  • 原文地址:https://www.cnblogs.com/randy-lo/p/13375613.html
Copyright © 2020-2023  润新知