洛谷P4839 P哥的桶 线段树+线性基

本文介绍了一种数据结构算法,使用线段树维护区间线性基,以解决插入数值和查询区间异或和的问题。通过维护每个节点的线性基,可以有效地进行区间更新和查询操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给出 q ≤ 5 e 4 q\leq5e4 q5e4个操作,在 k k k位置插入一个 x x x的数或者查询区间异或和最大为多少。同样是每个结点维护区间的线性基,线段树暴力合并。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const ll INF=LONG_LONG_MAX;
const int N=5e4+7;
int b[N<<2][31];
int ans[31];
void add(int b[],int x) {
	for(int i=30;i>=0;i--) {
		if(x&(1<<i)) {
			if(!b[i]) {
				b[i]=x;
				break;
			}
			else x^=b[i];
		}
	}
}
void pushup(int rt) {
	for(int i=30;i>=0;i--)
		b[rt][i]=b[rt<<1][i];
	for(int i=30;i>=0;i--)
		add(b[rt],b[rt<<1|1][i]);
}
void modify(int rt,int l,int r,int k,int x) {
	if(l==r) {
		add(b[rt],x);
		return;
	}
	int mid=(l+r)>>1;
	if(k<=mid) modify(rt<<1,l,mid,k,x);
	else modify(rt<<1|1,mid+1,r,k,x);
	pushup(rt);
} 
void query(int rt,int l,int r,int L,int R) {
	if(R<l||L>r) return;
	if(L<=l&&r<=R) {
		for(int i=30;i>=0;i--) {
			add(ans,b[rt][i]);
		}
		return; 
	}
	int mid=(l+r)>>1;
	query(rt<<1,l,mid,L,R);
	query(rt<<1|1,mid+1,r,L,R);
}
int main() {
	int q,n;
	scanf("%d%d",&q,&n);
	while(q--) {
		int opt,l,r,k,x;
		scanf("%d",&opt);
		if(opt==1) {
			scanf("%d%d",&k,&x);
			modify(1,1,n,k,x);
		}
		if(opt==2) {
			scanf("%d%d",&l,&r);
			for(int i=30;i>=0;i--)
				ans[i]=0;
			query(1,1,n,l,r);
			int res=0;
			for(int i=30;i>=0;i--) {
				if((res^ans[i])>res) {
					res^=ans[i];
				}
			}
			printf("%d\n",res);
		} 
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值