线性基求交
定义线性空间
-
引理:令
,若 线性无关,则 是所求的 之一。证明:考虑反面证明,若
非法则线性有关,设 且不能被 表出。那么有
,且 。因为
,同时 ,所以 就可以被 表出则
线性相关。
考虑如何求出
-
-
可以被 表出设
被 表出,则将 加入 。 -
否则不做任何操作。
-
证明这样可以求出
设
则有
证毕。
实现:
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;
}
};
例题:
牛客884B
给定
个线性基,问 的线性基是否都能够表出
考虑先建立线段树,该节点代表子树内所有线性基的交。
然后查询时在分的log个线性基里各自查询即可。
复杂度
一个新的线性基求交方法
只适用于异或线性基
参考:link
现在的问题就是如何求出正交补的基。
考虑设线性基为
然后考虑构造正交补线性基
将
然后对每一个
for(int i=n-1;~i;--i){
if(a[i]==0){
b[i]=1<<i;
for(int j=n-1;j>i;--j)if((a[j]>>i)&1)b[i]|=(1<<j);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!