线性基

在线性空间中,线性基是一组线性无关的向量组,且在其所在的向量空间中是一个极大线性无关向量组

我们在算法里,可以看作是若干个数的集合

在一个序列中,取其线性基中的任意几个数,可以得到原来序列的任何一个数

线性基中的数都是唯一的

如何构造线性基

贪心的方法

从高位往低位扫,设a[x]为第x位上是1的数,当前要加入的数为p

如果a[x]不存在,则p加入到该位上

如果a[x]存在,则p需异或一遍a[x],使得p的第x位不是1

从高位往低位扫,可以保证它是类似阶梯型的

复制代码
 1 void insert(int x)
 2 {
 3     for(int i=63;i>=0;i--)
 4     {
 5         if(!(x>>i))continue;
 6         if(!p[i])
 7         {
 8             p[i]=x;
 9             break;
10         }
11         x^=p[i];
12     }
13 }
复制代码

 

重构线性基

重构线性基的目的在于查找第k小的异或和

我们依次给第i位的i-1到0异或上对应的a,则可以得到1,10,100,这样子方便我们获得第k小的异或和

但是注意了,这种重构后的线性基无法通过异或获得0,所以如果原来的异或和可以得到0,则需特判一下

复制代码
 1 void rebuild()
 2 {
 3     tot=0;
 4     for(int i=0;i<=63;i++)
 5     {
 6         for(int j=i-1;j>=0;j--)
 7         {
 8             if((p[i]>>j)&1)p[i]^=p[j];
 9         }
10         if(p[i])d[tot++]=p[i];
11     }
12 }
13 
14 int get_min(int k)
15 {
16     if(tot!=n)k--;//去掉异或出来是0的情况
17     if(k>=(1<<tot))return -1;
18     int res=0;
19     for(int i=0;i<tot;i++)if((k>>i)&1)res^=d[i];
20     return res;
21 }
复制代码

 

posted @   rw156  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示