BZOJ 3261: 最大异或和|可持久化Tire树

a[i] 为前 i 个数的异或和, Ans=x(xor)a[n](xor)a[p1] 使其最大化,然后可以用可持久化Tire树来维护一下.
数组开的一定要够大,1000W还是会跪!!!!

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
#define mx 1e9
#define lowbit(x) (x&(-x))
#define N 505
using namespace std;
int sc()
{
    int i=0,f=1; char c=getchar();
    while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();
    return i*f;
}
int ch[14000050][2],sum[14000050];
int v[600066],root[600066];
int n,cnt,Sum,m;
void add(int pre,int &x,int w,int k)
{
    if(!x)x=++cnt;
    sum[x]=sum[pre]+1;
    if(!k)return;
    bool e=(w&k);
    ch[x][!e]=ch[pre][!e];
    add(ch[pre][e],ch[x][e],w,k>>1);
}
int ask(int l,int r,int x)
{
    int k=1<<24,ans=0;
    while(k)
    {
        bool e=!(x&k); 
        if(sum[ch[r][e]]-sum[ch[l][e]])
            ans+=k,r=ch[r][e],l=ch[l][e];
        else
            r=ch[r][!e],l=ch[l][!e];
        k>>=1;
    }
    return ans;
}
int main()
{
    n=sc()+1;m=sc();v[1]=0;
    for(int i=2;i<=n;i++)v[i]=v[i-1]^sc();
    for(int i=1;i<=n;i++)
        add(root[i-1],root[i],v[i],1<<24);
    for(int i=1;i<=m;i++)
    {
        char s[10];
        scanf("%s",s);
        if(s[0]=='A')
            ++n,v[n]=v[n-1]^sc(),
            add(root[n-1],root[n],v[n],1<<24);
        else
        {
            int l=sc()-1,r=sc(),x=sc()^v[n];
            printf("%d\n",ask(root[l],root[r],x));
        }
    }
    return 0;
}

你可能感兴趣的:(可持久化Tire树)