BZOJ3261

Posted Stump

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ3261相关的知识,希望对你有一定的参考价值。

http://www.lydsy.com/JudgeOnline/problem.php?id=3261

可持久化Tire+异或前缀和+贪心

可持久化Tire表示二进制数其实就是可持久化的值域线段树
每次贪心地构造最优解
#include<cstdio>
#define FOR(i,s,t) for(register int i=s;i<=t;++i)
const int NlogN=16000011,N=1000011;
int tot;
namespace Tire_Tree{
	struct Tire{
		int to[2];
		int sum;
	}tr[NlogN];
	int root[N];
	inline void insert(int cpy,int &now,int v,int dep){
		tr[now=++tot]=tr[cpy];
		++tr[now].sum;
		if(dep==-1)return;
		int t=(v>>dep)&1;
		insert(tr[cpy].to[t],tr[now].to[t],v,dep-1);
	}
	inline int query(int l,int r,int v){
		int t,ans=0;
		for(register int i=23;~i;--i){
			t=((v>>i)&1)^1;
			if(tr[tr[r].to[t]].sum>tr[tr[l].to[t]].sum){
				ans|=(1<<i);
				l=tr[l].to[t];r=tr[r].to[t];
			}
			else{
				t^=1;
				l=tr[l].to[t];r=tr[r].to[t];
			}
		}
		return ans;
	}
}
using namespace Tire_Tree;
int n,m;
int a[N],b[N];
char s[5];
int l,r,x;
int main(){
	scanf("%d%d",&n,&m);++n;
	FOR(i,2,n)scanf("%d",a+i);
	FOR(i,1,n)insert(root[i-1],root[i],b[i]=b[i-1]^a[i],23);
	while(m--){
		scanf("%s",s);
		if(s[0]==‘A‘){
			++n;
			scanf("%d",a+n);
			insert(root[n-1],root[n],b[n]=b[n-1]^a[n],23);
		}
		else{
			scanf("%d%d%d",&l,&r,&x);
			printf("%d\n",query(root[l-1],root[r],(b[n]^x)));
		}
	}
	return 0;
}

  

以上是关于BZOJ3261的主要内容,如果未能解决你的问题,请参考以下文章

[BZOJ3261]最大异或和

BZOJ 3261 最大异或和

bzoj3261

Bzoj3261 最大异或和

BZOJ3261:最大异或和——题解

bzoj3261最大异或和