再谈线性基
发布日期:2021-06-24 04:57:50 浏览次数:7 分类:技术文章

本文共 3934 字,大约阅读时间需要 13 分钟。

 

 

可参考神犇博客:

一、线性基介绍

 

1、线性基:

  若干数的线性基是一组数a1,a2,...an,其中ax的最高位的1在第x位。

  通过线性基中元素xor出的数的值域与原来的数xor出数的值域相同。

 

2、线性基的构造法:

  对每一个数p从高位到低位扫,扫到第x位为1时,若ax不存在,则ax=p并结束此数的扫描,否则令p = p  xor ax。(此处若此位存在,则必然存在有更高位的二进制数的1在此位置,异或则会使本身变优

 

3、查询:

  用线性基求这组数xor出的最大值:从高往低扫ax,若异或上ax使答案变大,则异或。

 

4、判断:

  用线性基求一个数能否被xorxor出:从高到低,对该数每个是1的位置x,将这个数异或上ax(注意异或后这个数为1的位置和原数就不一样了),若最终变为0,则可被异或出。当然需要特判0(在构造过程中看是否有p变为0即可)。例子:(11111,10001)的线性基是a5=11111,a4=01110,要判断11111能否被xor出,11111 xor a5=0,则这个数后来就没有是1的位置了,最终得到结果为0,说明11111能被xor出。

 

 

个人谈一谈对线性基的理解:

  很多情况下,只有有关异或运算和求最值,就可以用到线性基。线性基有很多很好的性质,比如说如果有很多个数,我们可以构出这些数的线性基,那么这个线性基可以通过互相xor,能够构出原来的数可以相互xor构出的所有的数。所以可以大大减少判断的时间和次数。同时线性基的任何一个非空子集都不会使得其xor和为0,证明也很简单,反证法就可以说明。这个性质在很多题目中可以保证算法合法性,比如:BZOJ2460

 

  构造的方法有点像贪心,从大到小保证高位更大。也比较好理解。就是这几行代码:

  

  

1 for(int i=1;i<=n;i++) {     2   3         for(int j=62;j>=0;j--) { 4   5              if(!(a[i]>>j)) continue;//对线性基的这一位没有贡献            6   7                if(!p[j]) { p[j]=a[i]; break; }//选入线性基中                    8   9                a[i]^=p[j];10  11              }12  13        }

 

 

  可以把n个数变成只有最大的数的二进制位数那么多个数,这就是线性基的优秀之处。

 

  查询的话,也是一个贪心思想,如果可以使得ans更大,就把这一位的基xorans

   1 for(int i=62;i>=0;i--) if((ans^p[i])>ans) ans=ans^p[i];//从线性基中得到最大值 

  这就是线性基的基本用法和个人的一些理解。

 

二、线性基模板

更新下线性基的模板

 

1 #include
2 #include
3 using namespace std; 4 typedef long long int ll; 5 const int maxn = 1e5 + 7; 6 const int mod = 1e9 + 7; 7 struct Linear_Basis { 8 ll b[63], nb[63], tot; //b为线性基 nb用来求第K小异或值 tot为nb元素个数 9 bool flag = false; 10 void init() { //初始化 11 tot = 0; 12 flag = false; 13 memset(b, 0, sizeof(b)); 14 memset(nb, 0, sizeof(nb)); 15 } 16 void ins(ll x) { //插入 17 for(int i = 62; i >= 0; i--) { 18 if(x & (1ll << i)) { 19 if(!b[i]) { 20 b[i] = x; 21 return; 22 } 23 x ^= b[i]; 24 } 25 } 26 flag = true; 27 return; 28 } 29 bool fin(ll x) { //验证存在性 30 if(x == 0 && b[0]) 31 return 1; 32 for(int i = 62; i >= 1; i--) { 33 int j = i - 1; 34 if(x & (1 << j)) { 35 x ^= b[i]; 36 if(!x) 37 return 1; 38 } 39 } 40 return 0; 41 } 42 ll Max(ll x) { //求最大值 43 ll res = x; 44 for(int i = 62; i >= 0; i--) { 45 res = max(res, res ^ b[i]); 46 } 47 return res; 48 } 49 ll Min(ll x) { //求最小值 50 ll res = x; 51 for(int i = 0; i <= 62; i++) { 52 if(b[i]) 53 res ^= b[i]; 54 } 55 return res; 56 } 57 ll Rebuild() { //第K大 58 for(int i = 62; i >= 0; i--) { 59 if(b[i] == 0) 60 continue; 61 for(int j = i - 1; j >= 0; j--) { 62 if(b[j] == 0) 63 continue; 64 if(b[i] & (1ll << j)) 65 b[i] ^= b[j]; 66 } 67 } 68 for(int i = 0; i <= 62; i++) { 69 if(b[i]) 70 nb[tot++] = b[i]; 71 } 72 } 73 ll Kth_Max(ll k) { 74 if(flag) 75 k--; //??? 76 ll res = 0; 77 if(k == 0) 78 return 0; 79 if(k >= (1ll << tot)) 80 return -1; 81 for(int i = 62; i >= 0; i--) { 82 if(k & (1ll << i)) 83 res ^= nb[i]; 84 } 85 return res; 86 } 87 } LB; 88 void merge(Linear_Basis &a, Linear_Basis &b) { //a和b都变成a+b 89 for(int i = 31; i >= 1; i--) { 90 if(b.b[i] == 0) 91 continue; 92 a.Ins(b.b[i]); 93 } 94 b = a; 95 } 96 int main() { 97 int n; 98 scanf("%d", &n); 99 return 0;100 }
线性基

 

 

三、线性基好题

 题目:

转载于:https://www.cnblogs.com/DWVictor/p/10522426.html

转载地址:https://blog.csdn.net/weixin_30346033/article/details/96130031 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:【Quartz】Quartz的搭建、应用(单独使用Quartz)
下一篇:mysql 授权

发表评论

最新留言

关注你微信了!
[***.104.42.241]2024年04月15日 17时12分35秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

“中文编程”知乎专栏两岁了——山雨欲来风满楼 2019-04-26
大疆机甲大师Python API之七:做个闹钟 2019-04-26
【意外走向】大疆机甲大师Python API之八:计时——为性能测试展开1000次循环 2019-04-26
RFC#2457——Rust 语言支持非 ASCII 码标识符在 GitHub 引发的激辩(一) 2019-04-26
RFC#2457——Rust 语言选择支持非 ASCII 码标识符在 GitHub 引发的激辩(二) 2019-04-26
”为什么有这么多人执着于中文编程?”回答两千赞留念及回应 2019-04-26
【家务】盘点小孩玩具零件缺失情况 2019-04-26
开发中文 API 的一些策略 2019-04-26
从日本编程书籍《我的第一本编程书》中译版看中文例程如何扬长避短——标识符(一) 2019-04-26
中文命名标识符如何区分类型和变量 2019-04-26
编程术语成系统中文化的意义 2019-04-26
草蟒 Python 中文 API 与 IDE 支持尝鲜 2019-04-26
一种改进中文 API 可读性的方法:参数不限于在末尾 2019-04-26
中文编程开发工具的生存模式探讨 2019-04-26
写给木兰编程语言研发团队的公开信 2019-04-26
为什么要急着为「木兰」编程语言贴上“造假”的标签? 2019-04-26
编程语言国产化的关键一战——对肆意污名化“木兰”编程语言说“不” 2019-04-26
各大媒体对「木兰」编程语言的不当言论盘点 2019-04-26
戳破针对「木兰」编程语言的拙劣谣言 2019-04-26
为「木兰」编程语言添加对中文命名标识符的支持 2019-04-26