BZOJ 3261: 最大异或和

Description

一个序列,支持两个操作.

1.在序列尾加入一个数.

2.询问 [l,r] 中与 x 异或值最大的数.

\(n\leqslant 3*10^5\)

Sol

可持久化 Trie 树.

跟主席树一样建二进值 Trie 树.

异或就是尽量找不相同的就行.

Code

/**************************************************************
    Problem: 3261
    User: BeiYu
    Language: C++
    Result: Accepted
    Time:4252 ms
    Memory:172380 kb
****************************************************************/
 
#include<cstdio>
#include<iostream>
using namespace std;
#define N 600055
inline int in(int x=0,char ch=getchar()){ while(ch>'9'||ch<'0') ch=getchar();
    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; }
inline char getop(char ch=getchar()){ while(ch>'Z'||ch<'A') ch=getchar();return ch; }
struct Trie{
    int ch[N*24][2],s[N*24],cnt;
    void insert(int pre,int &o,int val,int w){
        if(!o) o=++cnt;s[o]=s[pre]+1;if(!w) return;
        if(val&w) ch[o][0]=ch[pre][0],insert(ch[pre][1],ch[o][1],val,w>>1);
        else ch[o][1]=ch[pre][1],insert(ch[pre][0],ch[o][0],val,w>>1);
    }
    int Query(int L,int R,int val,int res=0){
        for(int k=1<<24,tmp;k;k>>=1){
            if(tmp=!(val&k),s[ch[R][tmp]]-s[ch[L][tmp]]) res+=k,L=ch[L][tmp],R=ch[R][tmp];
            else L=ch[L][!tmp],R=ch[R][!tmp];
        }return res;
    }
}t;
int rt[N];
int main(){
    int n=in()+1,m=in(),x;t.insert(rt[0],rt[1],0,1<<24);
    for(int i=2;i<=n;i++) x=x^in(),t.insert(rt[i-1],rt[i],x,1<<24);
    for(;m--;){
        char opt=getop();
        if(opt=='A'){
            x=x^in(),n++;t.insert(rt[n-1],rt[n],x,1<<24);
        }else{
            int l=in(),r=in(),v=x^in();printf("%d\n",t.Query(rt[l-1],rt[r],v));
        }
    }return 0;
}

  

posted @ 2016-12-14 17:19  北北北北屿  阅读(110)  评论(0编辑  收藏  举报