解题思路:
题目要求的是a[p]^a[p+1]^……^a[n]^x的最大值。
而该式等于sum[p-1]^sum[n]^x,其中sum[i]表示a[1]^a[2]^……^a[i]。
sum[n]^x可以直接算出,所以我们相当于每次去区间[l-1,r-1]中贪心找异或(sum[n]^x)的最优值
可以像建主席树一样建一棵可持久化trie树,第i棵树储存1~i所有的sum值。每新加一个数字,就新开一条链,并把上面的cnt值加一。
查找区间[l-1,r-1]中是否有一个数,就看第r-1棵树减第l-2棵树对应节点的cnt是否为0。
这样就可以像普通的trie树一样从高位开始贪心了。
注意如果我们询问[1,r],就要用第r-1棵树减去第-1棵树,下标越界,所以要把所有位置后移一位,并在第1个位置建一棵表示0的trie数代表sum[0]=0。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int getint()
{
int i=0,f=1;char c;
for(c=getchar();(c<'0'||c>'9')&&c!='-';c=getchar());
if(c=='-')f=-1;
for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';
return i*f;
}
const int N=600005;
struct node
{
int son[2],cnt;
}tr[N*30];
int n,m,tot,ans,rt[N];
char s[2];
void Insert(int &x,int y,int d,int num)
{
tr[x=++tot]=tr[y],tr[x].cnt++;
if(d<0)return;
int t=num&(1<<d)?1:0;
Insert(tr[x].son[t],tr[y].son[t],d-1,num);
}
void query(int x,int y,int d,int num)
{
if(d<0)return;
int t=num&(1<<d)?1:0,dl=tr[tr[x].son[t^1]].cnt,dr=tr[tr[y].son[t^1]].cnt;
if(dr-dl)ans|=(1<<d),query(tr[x].son[t^1],tr[y].son[t^1],d-1,num);
else query(tr[x].son[t],tr[y].son[t],d-1,num);
}
int main()
{
//freopen("lx.in","r",stdin);
n=getint()+1,m=getint();
int sum=0,l,r,x;
Insert(rt[1],rt[0],24,0);
for(int i=2;i<=n;i++)
{
x=getint();sum^=x;
Insert(rt[i],rt[i-1],24,sum);
}
while(m--)
{
scanf("%s",s);
if(s[0]=='A')
{
x=getint();sum^=x;
Insert(rt[++n],rt[n],24,sum);
}
else
{
l=getint()+1,r=getint()+1,x=getint();
x^=sum;ans=0;
query(rt[l-2],rt[r-1],24,x);
cout<<ans<<'\n';
}
}
return 0;
}