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;
}

  

posted @ 2017-12-11 22:21  Stump  阅读(163)  评论(0编辑  收藏  举报