2017ICPC西安现场赛 XOR(线段树合并线性基)

本文介绍了一种解决给定序列和整数k的异或问题,通过构建线性基和线段树,能够在O(nlogn)时间内高效地找到每次询问区间内的k模异或最大值。关键步骤包括对k取反并应用于序列,使用线性基合并操作来维护区间异或值。

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

题目链接:https://nanti.jisuanke.com/t/A1607

题目大意 :给你长度为n的序列,以及一个数k,有q次询问,每一次询问给你一个区间[L,R],然后你可以在区间内取任意多个数(每个数只能去一次),异或这些数得到一个值val,使得k|val的最值大,输出这个最大值

分析:或(|)操作,我们知道对应二进制为只要有一个1,结果就为1,所以我们让k|val最大,必须把k的高位0尽可能变为1,那么我们对k的二进制位取反得到一个数x,也变成了我们尽可能保留x的高位1,所以我们把原序列的所有数字对x&操作,也即a[1~n]&x,得到一个新的序列,对于一个询问区间[L,R],我们只需要求出这个区间的数异或得到的最大值即可,这是我们就可以使用线性基来O(n)求得异或最大值,换言之我们还需要维护新序列的线性基,所以我们可以通过线段树合并线性基的操作来快速维护区间的线性基
时间复杂度O(nlogn),因为合并线性基最多只有32位,所以可以忽略不计.

如果没有学过线性基的可以看下面视频
视频链接1:https://www.bilibili.com/video/BV1qK4y1p7p9?from=search&seid=6100927719987938288
视频链接2:https://www.bilibili.com/video/BV1ct411c7EP?from=search&seid=13154213484053366422

AC代码:

/*线段树合并线性基区间操作
线性基用于求一个集合取任意个数合并得到的最大值或求第K小值*/
#include<bits/stdc++.h>
#define ls dep<<1
#define rs dep<<1|1 
using namespace std;
const int Maxn = 1e4+10;
int n,q,k;
struct node{
   
   
	int mx;
	int d[31];
	void init(){
   
   
		memset(d,0,sizeof(d));
		return ;
	}
	/*结构体构造函数,结构体被创建时调用*/
	node(){
   
   
		memset(d,0,sizeof(d));
		mx = 30;
		return ;
	}
	bool add(int x){
   
   
		for(int i
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值