BZOJ3261最大异或和(可持久化字典树)

来源:互联网 发布:大学生网络诈骗图片 编辑:程序博客网 时间:2024/06/09 18:42
#include<bits/stdc++.h>using namespace std;const int MAXN=600000+10;int a[MAXN],b[MAXN];int tri[MAXN*25][2],sum[MAXN*25][2];int root[MAXN],cnt;void insert(int wei,int &x,int y,int vl){    if(wei<0)return;    x=++cnt;    int tmp=((vl>>wei)&1);    sum[x][tmp]=sum[y][tmp]+1;    sum[x][tmp^1]=sum[y][tmp^1];    tri[x][tmp^1]=tri[y][tmp^1];    insert(wei-1,tri[x][tmp],tri[y][tmp],vl);}int query(int wei,int x,int y,int vl){    if(wei<0)return 0;       int tmp=((vl>>wei)&1);    if(sum[y][tmp^1]-sum[x][tmp^1]!=0){        return (1<<wei)+query(wei-1,tri[x][tmp^1],tri[y][tmp^1],vl);    }    else return query(wei-1,tri[x][tmp],tri[y][tmp],vl);}int main(){    int n,m;    scanf("%d%d",&n,&m);    insert(23,root[1],root[0],0);    for(int i=2;i<=n+1;i++){        scanf("%d",&a[i]);        b[i]=b[i-1]^a[i];        insert(23,root[i],root[i-1],b[i]);    }    int step=n+1;    char str[2];    while(m--){        scanf("%s",str);        if(str[0]=='Q'){            int l,r,vl;            scanf("%d%d%d",&l,&r,&vl);            vl^=b[step];            printf("%d\n",query(23,root[l-1],root[r],vl));        }        else {            scanf("%d",&b[step+1]);            b[step+1]^=b[step];            insert(23,root[step+1],root[step],b[step+1]);            step++;        }    }    return 0;}