Loading

可持久化Trie 01Trie

可持久化Trie

基本上所有的可持久化数据结构都可以理解为继承与修改,继承之前的,再加入新的修改。
蛮好写的,size数组可以理解为在同一位深度的节点是第几个添加的,这样就为判断是在l前还是在l后准备了依据。

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<sstream>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<deque>
#include<cstdlib>
#include<ctime>
#define dd double
#define ld long double
#define ll long long
#define ull unsigned long long
#define N 50000000
#define M number
using namespace std;

const int INF=0x3f3f3f3f;

inline int read(){
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

struct PRE_TRIE{
    int root[N],ch[N][2],size[N],tail,tot;
    
    inline void insert(int sum){
        root[++tot]=++tail;
        int p=root[tot-1],q=root[tot];
        for(int i=30;i>=0;i--){
            int w=(sum>>i)&1;
            size[q]=size[p]+1;
            ch[q][w]=++tail;
            ch[q][w^1]=ch[p][w^1];
            q=ch[q][w];p=ch[p][w]; 
        }
        size[q]=size[p]+1;
    }
    
    inline int ask_max(int sum,int l,int r){
        int p=root[l-1],q=root[r],ans=0;
        for(int i=30;i>=0;i--){
            int w=(sum>>i)&1;
            if(size[ch[q][w^1]]-size[ch[p][w^1]]>0) q=ch[q][w^1],p=ch[p][w^1],ans+=(1<<i);
            else q=ch[q][w],p=ch[p][w];
        }
        return ans;
    }
};
PRE_TRIE trie;

int n,m,xhe;

int main(){
    n=read();m=read();
    trie.insert(0);
    for(int i=1;i<=n;i++){
        int x=read();xhe^=x;
        trie.insert(xhe);
    }
    for(int i=1;i<=m;i++){
        char c=getchar();
        while(c!='A'&&c!='Q') c=getchar();
        if(c=='A'){
            int x=read();xhe^=x;
            trie.insert(xhe);
        }
        else{
            int l=read(),r=read(),x=read();
            printf("%d\n",trie.ask_max(x^xhe,l,r));
        }
    }
    return 0;
}

学习博客

posted @ 2021-04-18 14:47  hyl天梦  阅读(102)  评论(0编辑  收藏  举报