线性基小节

1.线性基的异或集合中每个元素的异或方案唯一。
2.线性基二进制最高位互不相同。
3.线性基中元素互相异或,异或集合不变。

摘自百度文库

    线性基能相互异或得到原集合的所有相互异或得到的值。
    线性基是满足性质1的最小的集合
    线性基没有异或和为0的子集。

证明:
反证法:设线性基S={a1,a2...,an};
若有子集a1^a2^...^at=0,则a1=a2^a3^...^at,则舍弃a1后一定能通过剩余的元素异或出所有需要a1参与异或的值。设Y=a1^X,因为{a1,a2,...,an}是一组线性基,X一定能由a2...an中相互异或得来。
Y=a1^X=a2^a3^...^at^X,将X中在a2...at中出现的元素删去,在a2...at中未出现的元素加入,则也能异或得到Y,所以a1于线性基无用,与线性基是最小子集的定义矛盾。
所以:线性基没有异或和为0的子集。

线性基的本质是高斯消元,通过xor操作,将加减变成mod2意义下,也就是xor了。

解xor方程组用到了矩阵转置,也就是判断他们是不是线性无关的方法。我们需要维护一个线性无关的子集,并且删去的元素可以通过这个子集xor得到。

并且通过压位复杂度从63*63*63*n->63*n

//luogu3812
#include<bits/stdc++.h>
#define ll long long
#define cls(a,b) memset(a,b,sizeof(b))
using namespace std;

struct lb {
	ll d[61],p[61];
	lb() {cls(d,0);cls(p,0);}
	bool insert(ll n) {
		for(int i=60;i>=0;i--) {
			if((1ll<<i)&n) {
				if(!d[i]) {
					d[i]=n;
					break;
				}
				n^=d[i];
			}
		}

		return n>0;
	}

	ll get_mx() {
		ll ans=0;
		for(int i=60;i>=0;i--)
			if((ans^d[i])>ans)
				ans^=d[i];
		return ans;
	}

	ll get_mn() {
		for(int i=0;i<=60;i++)
			if(d[i])
				return d[i];
		return 0;
	}
}b;
ll n,x;

main() {
	cin>>n;
	for(int i=1;i<=n;i++) scanf("%lld",&x),b.insert(x);
	cout<<b.get_mx();
}
时间: 2024-10-04 10:08:30

线性基小节的相关文章

Xor HYSBZ - 2115 (线性基)

Xor HYSBZ - 2115 题意:给一个树,求1到n的最长路径.这里的路径定义为异或和. 线性基~~ 1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 struct LiBase{ 5 ll a[63]; 6 //初始化 7 void init(){ 8 memset(a,0,sizeof(a)); 9 } 10 //插入 11 bool insert_(ll x){ 12 for(int

[BeiJing2011]元素[贪心+线性基]

2460: [BeiJing2011]元素 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1245  Solved: 652[Submit][Status][Discuss] Description 相传,在远古时期,位于西方大陆的 Magic Land 上,人们已经掌握了用魔法矿石炼制法杖的技术.那时人们就认识到,一个法杖的法力取决于使用的矿石.一般地,矿石越多则法力越强,但物极必反:有时,人们为了获取更强的法力而使用了很多矿石,却在炼制过程中

BZOJ 3105: [cqoi2013]新Nim游戏 [高斯消元XOR 线性基]

以后我也要用传送门! 题意:一些数,选择一个权值最大的异或和不为0的集合 终于有点明白线性基是什么了...等会再整理 求一个权值最大的线性无关子集 线性无关子集满足拟阵的性质,贪心选择权值最大的,用高斯消元判断是否和已选择的线性相关 每一位记录pivot[i]为i用到的行 枚举要加入的数字的每一个二进制为1的位,如果有pivot[i]那么就异或一下(消元),否则pivot[i]=这个数并退出 如果最后异或成0了就说明线性相关... #include <iostream> #include &l

【BZOJ2844】albus就是要第一个出场 线性基 高斯消元

#include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/43456773"); } 题意:需要注意的是空集(0)是天生被包括的,我为了这个WA了好久~拍了好久,醉了好久~ 题解: 首先有一个我并不知道是为什么(甚至不知道它对不对)的性质: 每一种权值会出现2的自由元(n-线性基个数)次方 次. 感性

[bzoj 2460]线性基+贪心

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2460 网上很多题目都没说这个题目的证明,只说了贪心策略,我比较愚钝,在大神眼里的显然的策略还是想证明一下才安心--所以这里记录一下证明过程. 贪心策略:按魔力值从大到小排序,从大往小往线性基里插,如果成功插入新元素,就选这个,如果插不进去,就不选这个. 证明: 设有n个材料,每个材料的属性值是x[1],x[2],...,x[n],魔力值是v[1],v[2],...,v[n],这里假设v已

BZOJ 2460 元素(贪心+线性基)

显然线性基可以满足题目中给出的条件.关键是如何使得魔力最大. 贪心策略是按魔力排序,将编号依次加入线性基,一个数如果和之前的一些数异或和为0就跳过他. 因为如果要把这个数放进去,那就要把之前的某个数拿出来,而这样交换之后集合能异或出的数是不会变的,和却变小了. # include <cstdio> # include <cstring> # include <cstdlib> # include <iostream> # include <vector

线性基 学习笔记

ps:做CF的时候碰到了一个线性基的概念,然后在网上学习了一下,发现相关的资料很少,所以打算来写一个我个人的理解. 线性代数中 有极大线性无关组和空间的基的概念.  线性基的性质与此类似. 首先来看一个问题: 给出N个数,要从中选出一个最大的子集,使得子集中的任意个元素异或值不为0. 这个和极大线性无关组有些类似.异或可以看出是模2域下的加法运算,如果把一个数转化为二进制,对应成一个由01构成的向量, 所有这些向量就构成了一个线性空间. 原问题就转化为求这个向量组的极大线性无关组,把这样一个极大

【线性基】hdu3949 XOR

给你n个数,问你将它们取任意多个异或起来以后,所能得到的第K小值? 求出线性基来以后,化成简化线性基,然后把K二进制拆分,第i位是1就取上第i小的简化线性基即可.注意:倘若原本的n个数两两线性无关,也即线性基的大小恰好为n时,异或不出零,否则能异或出零,要让K减去1. 这也是线性基的模板. #include<cstdio> #include<cstring> using namespace std; typedef long long ll; ll d[64],p[64]; int

HDU 3949 XOR(线性基)

题意:给出一组数,求最小的第k个由这些数异或出来的数. 先求这组数的线性基.那么最小的第k个数显然是k的二进制数对应的线性基异或出来的数. # include <cstdio> # include <cstring> # include <cstdlib> # include <iostream> # include <vector> # include <queue> # include <stack> # includ