洛谷 P4735 最大异或和

一、题目:

洛谷原题

二、思路:

这是一道可持久化trie的板子题。

三、代码:

#include<iostream>
#include<cstdio>
#include<cstring>

#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define mem(s,v) memset(s,v,sizeof(s))

using namespace std;
inline LL read(void){
	LL 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 f*x;
}

const int maxn=600010;

int n,m;

int a[maxn],sum[maxn],root[maxn];

int trie[maxn*24][2],sz;
int latest[maxn*24];

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

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

int main(){
    n=read();m=read();
    latest[0]=-1;
    root[0]=++sz;
    insert(0,23,0,root[0]);
    for(register int i=1;i<=n;++i){
        a[i]=read();
        sum[i]=sum[i-1]^a[i];
        root[i]=++sz;
        insert(i,23,root[i-1],root[i]);
    }
    while(m--){
        char op[3];scanf("%s",op+1);
        if(op[1]=='A'){
            int x=read();
            root[++n]=++sz;
            sum[n]=sum[n-1]^x;
            insert(n,23,root[n-1],root[n]);
        }else{
            int l=read(),r=read(),x=read();
            printf("%d\n",ask(root[r-1],x^sum[n],23,l-1));
        }
    }
	return 0;
}

posted @ 2019-07-15 21:17  蓝田日暖玉生烟  阅读(123)  评论(0编辑  收藏  举报