线性基学习笔记

线性基解决的问题:

给定n个整数(数字可能重复),求在这些数中选取任意个,使得他们的异或和最大。

线性基是一个数列。

有原数列: a 1 a_1 a1, a 2 a_2 a2 a n a_n an,则它对应的线性基记为: p 1 p_1 p1, p 2 p_2 p2 p n p_n pn

注意:线性基是一个数组。

为什么叫这奇怪的名字…

p i p_i pi的意义就是:出现1的最高位为 i i i的数,当然是在二进制的表示下。

对于每个数,找出它最高位的1(在第 i i i 位),从而得到 p i p_i pi

如果 p i p_i pi为0,就加入线性基。

否则异或 p i p_i pi 继续寻找。

p p p 数组搞完后,从高位往低位,如果异或后答案变大,就异或,不然跳过。

得到最终答案。

不想证明。

洛谷线性基模板,代码:

#include<bits/stdc++.h>
using namespace std;
#define N 55
#define ll long long
ll n,ans,a[N],p[2*N];
void get(ll x){
	for(int i=62;i>=0;i--){
		if(!(x>>(ll)i))continue;
		if(!p[i]){p[i]=x;break;}
		x^=p[i];
	}
}
int main(){
	scanf("%lld",&n);
	for(register ll i=1;i<=n;i++)
	{scanf("%lld",&a[i]);get(a[i]);}
	for(int i=62;i>=0;i--){
		if((ans^p[i])>ans)ans=ans^p[i];
	}
	printf("%lld",ans);
	return 0;
} 

谢谢阅读。

洛谷同步。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值