BZOJ3261: 最大异或和
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3261
a[i]^...^a[j]=(a[1]^...^a[j])^(a[1]^...^a[i-1]) 。
然后建立可持久化trie搞就可以了。
#include<cstring> #include<iostream> #include<cstdio> #include<algorithm> #define rep(i,l,r) for (int i=l;i<=r;i++) #define down(i,l,r) for (int i=l;i>=r;i--) #define clr(x,y) memset(x,y,sizeof(x)) #define maxn 600500 #define inf int(1e9) #define ull unsigned long long #define seed 419 #define mm 1000000007 using namespace std; int s[maxn*30][2],bin[22],sum[maxn*30],root[maxn],n,m,cnt; int a[maxn],b[maxn]; char ch[2]; int read(){ int x=0,f=1; char ch=getchar(); while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while (isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();} return x*f; } void add(int d,int x,int &y,int val){ y=++cnt; sum[y]=sum[x]+1; if (d<0) return; s[y][0]=s[x][0]; s[y][1]=s[x][1]; int p=((val>>d)&1); if (p) add(d-1,s[x][1],s[y][1],val); else add(d-1,s[x][0],s[y][0],val); } int ask(int d,int x,int y,int val){ if (d<0) return 0; int p=((val>>d)&1); if (sum[s[y][p^1]]-sum[s[x][p^1]]>0) return (1<<d)+ask(d-1,s[x][p^1],s[y][p^1],val); else return ask(d-1,s[x][p],s[y][p],val); } int main(){ n=read(); m=read(); //bin[0]=1; rep(i,1,20) bin[i]=bin[i-1]*2; n++; add(24,root[0],root[1],0); rep(i,2,n) { a[i]=read(); b[i]=b[i-1]^a[i]; add(24,root[i-1],root[i],b[i]); } rep(i,1,m){ scanf("%s",ch); if (ch[0]=='A'){ n++; a[n]=read(); b[n]=b[n-1]^a[n]; add(24,root[n-1],root[n],b[n]); } else { int l=read(),r=read(),x=read(); printf("%d\n",ask(24,root[l-1],root[r],b[n]^x)); } } return 0; }