[学习笔记]省选(算法?数据结构?)·线性基
2018-02-03 15:50
495 查看
一、开头
神犇MX:怎么样?xyz32768,你学不会后缀自动机,真是菜啊!xyz32768:是啊,我本来就很菜啊!
神犇MX:你不服的话,再考你一道题:给定一个nn个数的数集,求一个子集,使这个子集的xorxor和最大?只需要输出这个xorxor和。n≤105n≤105并且每个数不大于260260。
xyz32768:爆搜子集,O(2n)O(2n),我好像只会这样了。
神犇MX:看来你还是太菜,连线性基都不会,怎么可能会后缀自动机呢?
xyz32768:啊啊啊啊啊啊啊啊啊啊啊啊啊啊……(省略1099999910999999个“啊”)
二、介绍
一个nn个数的正整数集合SS,这个集合的线性基是一个mm个正整数的集合:A={a1,a2,a3,...,am}A={a1,a2,a3,...,am}
线性基有两点性质:
①:如果存在S′⊂SS′⊂S且S′S′内元素的xorxor和为tt,那么就一定存在A′⊂AA′⊂A且A′A′内的元素的xorxor和为tt,反过来也一样。简单的说,通过AA集合内的元素xorxor出的值域与通过SS集合内的元素xorxor出的值域相同。
②:线性基还有一个重要的性质:对于任何一个ii,要么aiai不存在,要么aiai最高位的11在第ii位上。
三、构造(插入一个新数)
集合SS为空时,线性基即集合AA的每一个元素(即a1,a2,...a1,a2,...)都不存在。向线性基中插入新数pp的方法:
从高到低扫描pp的每一个二进制位,扫描到pp的第ii位为11时,分两种情况:
如果aiai不存在,那么令ai=pai=p并且结束扫描。
否则令p=p xor aip=p xor ai并继续扫描。
简单解释:假设插入新数pp之前的线性基为A′A′,设A′A′满足线性基的两个性质,那么在aiai不存在并且pp最高位的11在第ii位的情况下,令ai=pai=p,得到的线性基仍然满足性质。
而在aiai存在的情况下令p=p xor aip=p xor ai是为了使pp的第ii位为00,以此维护性质②。这时候pp异或上aiai之后等于待插入的新数,而两个相等的数的异或值总是00,这时候仍然满足线性基的性质①。
代码(代码中的orzorz表示线性基,orzi=−1orzi=−1就表示orziorzi不存在):
void ins(ll p) { int i; for (i = m; i; i--) { if (!((p >> i - 1) & 1)) continue; if (orz[i] == -1) return (void) (orz[i] = p); else p ^= orz[i]; } }
合并两个线性基,就是把一个线性基中的元素暴力插入到另一个线性基里面。
代码:
cyx mer(cyx a, cyx b) { int i; for (i = m; i; i--) a.ins(b.orz[i]); return a; }
四、查询
1、最大异或和
贪心。从高往低扫aa,对于一个aiai,如果aiai存在,并且异或上aiai后会使结果更大,就异或上aiai。通过性质②可以得出正确性。代码:
ll max_xor() { int i; ll ans = 0; for (i = m; i; i--) if ((ans ^ orz[i]) > ans) ans ^= orz[i]; return ans; }
2、一个数pp能否被异或出
贪心,同样是利用性质②。首先记下res=0res=0。从高往低扫aa。对于一个aiai,如果aiai存在,并且resres的第ii位与pp的第ii位不等,则使res=res xor aires=res xor ai。
如果最后res=pres=p,那么pp能被异或出。当然需要特判00:
如果SS中有00,或者在构建线性基的过程中,存在一个待插入的数kk使得插入之前kk能被异或出,那么存在一个非空子集的异或和为00。
代码(不加特判00):
bool _xor(ll p) { int i; ll res = 0; for (i = m; i; i--) { if (orz[i] == -1) continue; if (((p >> i - 1) & 1) != ((res >> i - 1) & 1)) res ^= orz[i]; } return res == p; }
五、题目
(待补充)相关文章推荐
- 数据结构与算法学习笔记——队列
- 【算法学习笔记】08.数据结构基础 二叉树初步练习1
- 【算法学习笔记】10.数据结构基础 二叉树初步练习3(遍历与递归复习)
- 数据结构与算法基础学习笔记
- 【算法学习笔记】12.数据结构基础 图的初步1
- 【算法学习笔记】06.数据结构基础 队列与堆栈初步
- 数据结构与算法学习笔记03(腾讯面试题)
- 【算法学习笔记】09.数据结构基础 二叉树初步练习2
- 【算法学习笔记】08.数据结构基础 二叉树初步练习1
- 【算法学习笔记】12.数据结构基础 图的初步1
- 【学习笔记】数据结构与算法基础学习:链表
- 数据结构与算法学习笔记02_1(线性表)
- 数据结构与算法-学习笔记2
- 【算法学习笔记】11.数据结构基础 二叉树初步练习4
- 【算法学习笔记】07.数据结构基础 链表 初步练习
- 数据结构与算法学习笔记——动态规划(1)
- 数据结构与算法学习笔记——链表部分实现(数组形式)
- 【算法学习笔记】09.数据结构基础 二叉树初步练习2
- JAVA 数据结构与算法学习笔记一(转载)
- 数据结构与算法学习笔记——quick sort