可持久化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;
}

posted on 2026-01-06 21:02  _CENSORED  阅读(24)  评论(0)    收藏  举报

导航