BZOJ 4184: shallot

题目大意:

有两种操作,加入数,删除数,问每次操作后最大xor和

题解:

每个数字出现的时间是一段区间

线段树维护线性基,区间插入

有人说卡内存,但是没发现哪里会爆内存。

代码:

#include<cstdio>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
int a[4000005],b[4000005];
map<int,int> M;
vector<int> tag[4000005];
void insert(int t,int l,int r,int x,int y,int key){
	if (r<x || l>y) return;
	if (l>=x && r<=y){
		tag[t].push_back(key);
		return;
	}
	int mid=(l+r)>>1;
	insert(t<<1,l,mid,x,y,key);
	insert(t<<1|1,mid+1,r,x,y,key);
}
void dfs(int t,int l,int r,int a[]){
	for (int i=0; i<tag[t].size(); i++){
		int x=tag[t][i];
		for (int j=30; j>=0; j--)
			if (x&(1<<j)){
				if (!a[j]){
					a[j]=x;
					break;
				}
				x^=a[j];
			}
	}
	int b[31],c[31];
	for (int i=0; i<=30; i++) b[i]=a[i],c[i]=a[i];
	if (l==r){
		int ans=0;
		for (int i=30; i>=0; i--)
			if ((ans^a[i])>ans) ans=ans^a[i];
		printf("%d\n",ans);
		return;
	}
	int mid=(l+r)>>1;
	dfs(t<<1,l,mid,b);
	dfs(t<<1|1,mid+1,r,c);
}
int main(){
	int n;
	scanf("%d",&n);
	for (int i=1; i<=n; i++){
		scanf("%d",&a[i]);
		M[a[i]]=i;
	}
	for (int i=1; i<=n; i++) 
		if (a[i]>0) {
			if (!M[-a[i]]) M[-a[i]]=n+1;
			insert(1,1,n,M[a[i]],M[-a[i]]-1,a[i]);
		}
	dfs(1,1,n,b);
	return 0;
}

  

转载于:https://www.cnblogs.com/silenty/p/9368349.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值