最大异或和-可持久化Trie
题目描述
题解
首先观察式子,根据异或的可加减性,可将其转化为式子 s [ p − 1 ] s[p-1] s[p−1] ^ s [ N ] s[N] s[N] ^ x x x( s [ x ] s[x] s[x]表示前缀异或和),于是可持久化Trie,每次查询区间 [ l − 1 , r − 1 ] [l-1,r-1] [l−1,r−1]
代码
(一直90分,wa一个点,不想调了)
#include<bits/stdc++.h>
#define M 600009
using namespace std;
int sum[M],ch[M*30][2],ed[M*30],cnt,n,m,rt[M];
int read(){
char ch;
int f=1,re=0;
for(ch=getchar();!isdigit(ch)&&ch!='-';ch=getchar());
if(ch=='-'){f=-1;ch=getchar();}
for(;isdigit(ch);ch=getchar()) re=(re<<3)+(re<<1)+ch-'0';
return re*f;
}
void build(int x,int y,int len,int val){
if(len<0) return;
int i=(val>>len)&1;
ch[y][!i]=ch[x][!i];
ch[y][i]=++cnt;
ed[ch[y][i]]=ed[ch[x][i]]+1;
build(ch[x][i],ch[y][i],len-1,val);
}
int solve(int x,int y,int len,int val){
if(len<0) return 0;
int i=(val>>len)&1;
if(ed[ch[y][!i]]>ed[ch[x][!i]])
return (1<<len)+solve(ch[x][!i],ch[y][!i],len-1,val);
else return solve(ch[x][i],ch[y][i],len-1,val);
}
int main(){
int x,y,z;
char s[10];
n=read(),m=read();
for(int i=1;i<=n;i++){
x=read(),rt[i]=++cnt;
sum[i]=sum[i-1]^x;
build(rt[i-1],rt[i],24,sum[i]);
}
for(int i=1;i<=m;i++){
scanf("%s",s);
if(s[0]=='A'){
x=read(),n++;
sum[n]=sum[n-1]^x,rt[n]=++cnt;
build(rt[n-1],rt[n],24,sum[n]);
}
if(s[0]=='Q'){
x=read(),y=read(),z=read();
if(x==1) printf("%d\n",solve(rt[x-1],rt[y-1],24,z^sum[n]));
else printf("%d\n",solve(rt[x-2],rt[y-1],24,z^sum[n]));
}
}return 0;
}