异或线性基小记
其实是
前置知识
向量
定义
定义如下运算:
,也就是每一维相乘,称为数乘。
线性组合与张成空间
定义向量集
线性相关
对于向量集
基
定义:若向量集
的任意真子集不是 的基- 对于任意
,存在唯一的 ,满足 是 以 为权的线性组合 - 对于任意线性有关集
,存在其真子集 满足
一个线性空间可能有多组基。
异或线性基
其实是
本质:
异或是
意义下的加法
将一个
类似地,我们定义张成空间:
- 定义序列
的张成空间 为从 中挑选若干数字可以异或得到的数字之和,换句话说就是 的所有子序列(可以空)元素异或和组成的集合
线性基的构造方法
构造线性基,我们考虑用增量法来构造线性基。假如现在要插入一个向量,从左向右不断消去1,直到出现了第一个无法消去的1,说明这个向量无法用现在的几组基底表示出来,所以将其插入线性基。
代码实现
ll d[65];
void ins(ll x){
for(int i=60;i>=0;i--)
if((x>>i)&1){
if(d[i])x^=d[i];
else{
d[i]=x;break;
}
}
}
性质:
- 序列
的线性基为 的一组基。 - 线性基是线性无关向量组
- 线性基里有值的元素个数所有张成空间是
的向量组里最少的。 - 设
为线性基,则
标准基,也称上三角基。
一个张成空间很可能不止一组基,而标准基寻求一种标准的表示方法。
我们将一般的线性基执行如下操作:
for(int i=60;~i;--i)if(d[i])for(int j=i-1;~j;--j)if((d[i]>>j)&1)d[i]^=d[j];
容易发现操作后的线性基同样也是原张成空间的基,且满足将该向量组写为
类似于阶梯型矩阵和简化阶梯型矩阵。
这相当有用。
应用
第 小异或和
将线性基化为标准基,设其按大小排序后是
读者自证不难
特别的,最大异或和就是全部异或起来,而
线性基合并
直接暴力把一个线性基插入另一个线性基即可。
线性基求交
定义线性空间
-
引理:令
,若 线性无关,则 是所求的 之一。证明:考虑反面证明,若
非法则线性有关,设 且不能被 表出。那么有
,且 。因为
,同时 ,所以 就可以被 表出则
线性相关。
考虑如何求出
-
-
可以被 表出设
被 表出,则将 加入 。 -
否则不做任何操作。
-
证明这样可以求出
设
则有
证毕。
struct node{
int d[32];
node(){
memset(d,0,sizeof d);
}
void ins(int x){
for(int i=31;i>=0;--i)if((x>>i)&1){
if(d[i])x^=d[i];
else {d[i]=x;return ;}
}
}
bool count(int x){
for(int i=31;i>=0;--i)if((x>>i)&1){
if(!d[i])return false;
x^=d[i];
}
return true;
}
node operator&(const node b)const {
node tmpa;memcpy(tmpa.d,d,sizeof d);
node uda=tmpa,res;
for(int i=0;i<32;++i)if(b.d[i]){
int x=b.d[i],sur=0,tag=1;
for(int j=i;j>=0;--j)if((x>>j)&1){
if(tmpa.d[j])x^=tmpa.d[j],sur^=uda.d[j];
else {tmpa.d[j]=x,uda.d[j]=sur,tag=0;break;}//uda.d[i] 指该元素使用的 B_1 中元素 xor 和
}
if(tag)res.ins(sur);
}
return res;
}
};
带删除线性基
肯定是离线的啦
考虑求出每个元素的删除时间
若当前线性基这一位的删除时间早于
,将 与这一位互换(注意 也需要互换),并继续向下插入 否则就异或后正常插入
查询时就将时间早于当前时间的位不考虑即可。
当然可以自然扩展到前缀线性基。
考虑对于原序列的每一段前缀,维护一个前缀线性基。
对于每个二进制位,维护可以贡献它的基底中下标最大的一个。
插入的时候如果存在基底,考虑将插入的数和基底中下标较小的一个继续向下插入,另一个作为当前位的基底。
查询只需要第
个前缀线性基中下标大于等于 的基底。
线性基与无向图路径
核心:无向图可以走回头路,那么一个环的异或值可以不耗任何代价得到
对于一个无向连通图,有边权,构建 DFS 树后,将所有环的权异或组成一个线性基,具有以下性质
- 这个线性基只需要所有返祖边所对应简单环异或和即可构建(其他环可以表达为这些环的复合)
- 点
的所有可能的路径的异或值均可以用这两者的简单路径的异或值与线性基中的值表出,这是因为走到一个环又走回去是可以抵消的,这时候产生贡献的只有环。 - 对于
所有路径的异或值,用 表示所有返祖边构成环的权值组成的线性基,则有将 加入 后, 的张成空间内的所有元素在原图都能够找到一条 的路径其异或值是这个(特判 )
计数的几个结论
-
里选出大小为 的线性无关向量组的方案数是: -
里本质不同 维子空间的个数是 -
里秩为 的矩阵个数是 转置原理运用:
让
个向量张成 维空间,相当于是求数 里有多少个 行 列矩阵满秩(这里并没有要求每一行不能够相同,也没有要求顺序(也就是讲顺序))转置后的等价于有多少个
行 列矩阵, 个向量线性无关。等价于
里选出大小无关的线性无关向量组的方案数
相关题目
幸运数字
给定一颗树,点有点权,多次询问,给出
,求树上 路径选出任意多个点的点权异或和最大值
等价于求出
可以利用前缀线性基的方法做一个后缀线性基,详细的说,求出线性基
那么每次相当于是拿出
复杂度
P 哥的桶
相当于给定
线段树暴力维护线性基合并即可,
新Nim游戏
考虑从大到小插入线性基,如果插入失败说明此数必选。
正确性:线性基上每一位尽可能让更大的数字占掉不劣。
CF1100F
相当于 P 哥桶的静态版本,每个位置只有一个数。
一个
但是更一般地我们采用前缀线性基做即可。
无力回天NOI2017
线性基不支持整体标记,所以我们需要找某些手段将区间修改变成单点修改。
不妨设
至于区间
那么就可以线段树暴力维护
CF959F
线性基性质的扩展。
证明:
我们知道,线性基每个元素是由某些元素异或得到,不妨将其也表达为一个向量(出现/不出现)
插入时,会判断
考虑到有
所以就是
CF938G
相当于每条边有存在时间,考虑可撤销带权并查集维护线段树分治,维护当前情况的线性基。
每走到一个节点时,保存当前的线性基用来撤销,这部分总
总插入复杂度是
插入边时,如果不连通,那么利用带权并查集也可以求出新边边权,如果连通那么成环,将其值插入线性基。
而总查询复杂度是
所以总复杂度
CF388D
本质上是求有多少个本质不同的线性基满足其最大异或值不超过
考虑我们只计数标准型线性基保证不重不漏。
那么设
将线性基元素
有如下限制:如果当前位作为某个线性基的最高位,那么这一列仅有这个有值。
转移考虑分类讨论:
-
当前不填
基本转移:
-
该位为 ,这是已经填过的线性基全部异或起来这一位取零,所以有 种方法 -
该位为对应一个取奇数个
,一个取偶数个 的 能否继续顶住上界。
-
-
当前要填
基本转移:
,这时候相当于该列全是零。 该位为零,算了 该位为 ,有
CF1299D
先断开所有与
注意到值域很小,本质不同的线性基只有
这相当于是求在所有连边方案里有多少个,拿出所有环异或值,异或不出
设
可以分讨:
- 该连通块内部环可以表出
,则必须全部断掉 - 只向这个连通块连一条边,仍然合法
- 向这个连通块连两条(如果存在),会产生新环,如果仍然合法,也可以加入 dp 转移。
八纵八横
注意到原图连通,因此可以先求出 dfs 树,然后将所有树上的简单环的异或值插入线性基
接着操作1,2都等价于动态加入/删除某个值
然后问最大 xor 值。
离线下来直接带删 bitset 即可。
CF1603 F
求有多少个长为
的非负整数序列 ,满足:
- 不存在一个非空子序列异或和是
由于是非空子序列,所以
首先可以注意到这等价于所有元素都可以成功插入线性基,也就是求有多少个
答案即为
此刻显然所有数字是等价的,因此不妨设
枚举向量组大小
也有一个容斥解释:可以表出
组合证明:
对于
对于
证明:
我们钦定这相当于是首先拿掉
后产生的大小为 的线性无关向量组 考虑如下构造:设最终的向量组是
,可以表出 。 枚举
,我们将构造如下 种方案。 由于
两两线性无关,那么将 。 然后
取 种: 是否异或上 ,因为两两线性无关,共会产生 种不同的 ,也就是 种 。 那么总的一个
可以构造出 种不同的 ,且显然不重 不漏也是显然的,我们相当于在整体枚举第一次
被表出的时刻。
求出基后,我们需要看有多少个
所以答案即为:
稍加预处理后可以
校内模拟赛 29th C
相当有意思的题目,也是我不会的题目
首先必然是给
考虑答案集合的上三角基,也就是标准基,有将其排序后按照
这启发我们根据
再将这个线性基化为标准基,则我们将
考虑这样的一对限制
同时对于答案求算,我们都算标准基
这给出了如下信息:
- 答案线性基里,
必须取 这一位 - 对于
低于最高位且为零的位置 ,也就是 ,这说明我们选择的答案标准基里相应的位置最终异或时这个位必须是零,那么告诉我们参与这个值异或的答案基位置最高位都不能是 。 - 对于
,这说明不参与这个值答案异或的答案基位置最高位不能够是
考虑这是否充分(这显然必要)
一个从低到高确定线性基的过程,当我们确定答案基第
所以,根据
那么有 dp:设
考虑转移:
- 令转移系数
当 时 ,否则
最终答案是考虑所有
difficult-ARC139F-sol
P10707 永恒
考虑先计数标准线性基个数,大小相同的线性基显然对应相同数量的可重集。
设
-
当前位
为 ,则有两个决策:这里放 ,或者前面 个放奇数个 。有:
,注意 时不进行转移。 -
当前位
位 ,则我们只能固定前面填的元素这一位有偶数个有:
, 时取 。
有了这个,我们可以知道
现在考虑设
由于这个是可重集,考虑dp(但是如果你枚举去重后的集合大小,利用公式算,然后可重就随意附加这样来就错完了,因为公式那个不计顺序(也就是顺序不同算不同),很难变成集合形式)。
考虑容斥,那么就还需要一个
(这里称
考虑从前往后转移,如果我舍弃当前这个最小基的元素,它就可以让前面的位随意的异或上它且由于线性无关可以产生不重复不漏的方案(注意这也是标准基)。
于是就有
根据插板法,那就有
答案即为
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!