可持久化Trie
/*
题目要求查询区间[l,r]异或和与一个值val的最大异或和
由a1a2...^an ^ a1a2...an=0与a0=a的性质
可以转化为pre[l-1]pre[r]valpre[n],其中valpre[n]是定值,只需要求出pre[l-1]^pre[r]的最大值
显然,如果一个一个求,效率极慢,但是,如果利用可持久化的思想,将相同部分的01值存储起来,再去
再贪心按照当前位的不同数前去寻找,(如1尽量去找一个子节点为0的,这样异或值最大,否则只能去找一个0)
就可以了
/
/
#include<iostream>
using namespace std;
const int N=6e5+5;
int pre[N];
int trie[N*20][2],tot,pos[N];//空间复杂度O(nlogn),tot为总点数,pos为节点对应的下标
//每个节点都有两个子节点0和1
int root[N],maxsiz=25;
//maxsiz,最大位数
void insert(int loc,int k,int u,int last){
int c=(pre[loc]>>k)&1;//取第k位
trie[u][c]=++tot;//创建新节点
if(k<0)
return ;
pos[u]=loc;
if(last)//另一子树复制上一版本(可持久化)
trie[u][c^1]=trie[last][c^1];
insert(loc,k-1,trie[u][c],trie[last][c]);
}
int query(int u,int k,int val,int lim){
if(k<0)
return pre[pos[u]]^val;
int c=(val>>k)&1;
if(pos[trie[u][c^1]]>=lim)
return query(trie[u][c^1],k-1,val,lim);
else
return query(trie[u][c],k-1,val,lim);
}
int main(){
cin.tie(nullptr)->sync_with_stdio(false);
int n,m;
cin>>n>>m;
root[0]=++tot;//询问范围[l,r],查询范围[l-1,r-1],所以要建一下
insert(0,maxsiz,root[0],0);
//root[-1]=0
for(int i=1;i<=n;i++){
int tmp;
cin>>tmp;
pre[i]=pre[i-1]^tmp;
root[i]=++tot;
insert(i,maxsiz,root[i],root[i-1]);
}
for(int i=1;i<=m;i++){
char ch;
cin>>ch;
if(ch=='A'){
int tmp;
cin>>tmp;
n++;
pre[n]=pre[n-1]^tmp;
root[n]=++tot;
insert(n,maxsiz,root[n],root[n-1]);
}
else{
int l,r,val;
cin>>l>>r>>val;
l--,r--;
val^=pre[n];
if(l==0)
cout<<query(root[r],maxsiz,val,0)<<'\n';
else
cout<<query(root[r],maxsiz,val,root[l-1])<<'\n';
}
}
}
*/
#include <bits/stdc++.h>
using namespace std;
#define maxn 600009
int rt[maxn],cnt[maxn*28];
int ch[maxn*28][2];
int qz[maxn];
int tt=1;
int n,m;
void ins(int a,int b,int t,int x) {
if(t<0) return;
int i=(x>>t)&1;
ch[a][!i]=ch[b][!i];
ch[a][i]=tt++;
cnt[ch[a][i]]=cnt[ch[b][i]]+1;
ins(ch[a][i],ch[b][i],t-1,x);
}
int qu(int a,int b,int t,int x) {
if(t<0) return 0;
int i=(x>>t)&1;
if(cnt[ch[b][!i]]>cnt[ch[a][!i]]) {
return (1<<t)+qu(ch[a][!i],ch[b][!i],t-1,x);
}
else {
return qu(ch[a][i],ch[b][i],t-1,x);
}
}
int main(){
scanf("%d%d",&n,&m);
int a,b,c,i,j;
char s[5];
rt[0]=tt++;
ins(rt[0],0,25,0);
for(a=1;a<=n;a++) {
scanf("%d",&b);
qz[a]=qz[a-1]^b;
rt[a]=tt++;
ins(rt[a],rt[a-1],25,qz[a]);
}
for(a=1;a<=m;a++) {
scanf("%s",s);
if(s[0]=='A') {
scanf("%d",&b);
n++;
qz[n]=qz[n-1]^b;
rt[n]=tt++;
ins(rt[n],rt[n-1],25,qz[n]);
}
else {
scanf("%d%d%d",&i,&j,&b);
i--;j--;
if(i==0) printf("%d\n",qu(0,rt[j],25,b^qz[n]));
else printf("%d\n",qu(rt[i-1],rt[j],25,b^qz[n]));
}
}
return 0;
}
浙公网安备 33010602011771号