[BZOJ3261]最大异或和 可持久化tire树

本文介绍了一种基于Trie树的数据结构实现,用于高效处理数组的查询和更新操作。通过将数组元素转换为二进制表示并构建Trie树,可以快速查找区间内满足特定条件的元素。文章详细描述了插入、搜索等核心算法,并提供了完整的代码实现。

[BZOJ3261]

  • tire树相关
  • 由于可能出现查询越界的情况,所以开始时要把初始数组整体向右移动一位

Code


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
const int N=6e5+100;
int 	tr[N*28][2],b[N],a[N],son[N*28],root[N],ans,tot,n,m,x,l,r;
char	s,shit[30],fuck[30];
inline int read(){
    int x=0;char ch=getchar();
    while(isdigit(ch)==0)ch=getchar();
    while(isdigit(ch)!=0){x=x*10+ch-'0';ch=getchar();}
    return x;
}
void zip(int a,char s[]){
	int top=28;
	while(a){
		if(a&1)s[top]='1';
		else s[top]='0';
		a>>=1;
		top--;
	}
	per(i,top,1)s[i]='0';
}
void insert(int &now,int last,int len){
	if(!now)now=++tot;
	if(len==29){
		son[now]=son[last]+1;
		return;
	}
	int to=shit[len]-'0';
	rep(i,0,1){
		if(i!=to){
			tr[now][i]=tr[last][i];
			son[now]+=son[tr[last][i]];
		}
	}
	insert(tr[now][to],tr[last][to],len+1);
	son[now]+=son[tr[now][to]];
}
void search(int r,int l,int len){
	if(len==29) return;
	if(fuck[len]=='0'){
		if(son[tr[r][1]]-son[tr[l][1]]){
			ans|=1<<(28-len);
			search(tr[r][1],tr[l][1],len+1);
		}else{
			search(tr[r][0],tr[l][0],len+1);
		}
	}else{
		if(son[tr[r][0]]-son[tr[l][0]]){
			ans|=1<<(28-len);
			search(tr[r][0],tr[l][0],len+1);
		}else{
			search(tr[r][1],tr[l][1],len+1);
		}
	}
}
int main()
{
	n=read(),m=read();
	++n;rep(i,2,n)a[i]=read();
	rep(i,1,n)b[i]=b[i-1]^a[i];
	rep(i,1,n)zip(b[i],shit),insert(root[i],root[i-1],1);
	while(m--){
		scanf(" %c",&s);
		if(s=='A'){
			b[++n]=read();
			b[n]^=b[n-1];
			zip(b[n],shit);insert(root[n],root[n-1],1);
		}else{
			l=read(),r=read(),x=read(); 
			x^=b[n],ans=0,zip(x,fuck);
			search(root[r],root[l-1],1);
			printf("%d\n",ans);
		}
	}return 0;
}

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值