关于我暑假学的,但是完全没学。
我不会线代,所以有关那个的部分直接跳了。
定义
关于这是个啥,我只找到一个还算确切的定义
对于一个序列 \(a_{1 \dots n}\),如果一个序列 \(d_{1\dots k}\) 满足如下性质,那就称 \(d\) 为 \(a\) 的一组线性基
- 能通过 \(a\) 异或出的数字也都能通过 \(d\) 的一堆子集异或出来。
- \(d\) 的任意一些元素不能异或出 \(0\)
- 满足前两条的条件下元素数量最少
这难道不是性质?
反正线性基是一种可爱的解决子集异或的问题的数据结构(?)
构造
上代码
void ins(ll x)
{
for(int i=59;i>=0;i--)
{
if(!(x&(1ll<<i))) continue;
if(!d[i]) {d[i]=x;break;}
x^=d[i];
}
}
我试图解释但是语言笨拙解释不清。
考虑将一个数字插入线性基。从高位向低位枚举,如果当前位是 \(0\) 的话直接跳过,如果是 \(1\) 的话看当前位有没有插入数字。如果有,直接将数字异或上存储的数字,否则,直接把当前数字留在这里,然后退出。
至于为什么能满足上面的性质:
- \(a\oplus b=c\) 可以得到 \(a\oplus c=b\),所以 \(x\oplus d_i=d_j\)(由构造方式得出),也可以得到 \(d_i \oplus d_j=x\),那么原序列中的任意一个数都可以由线性基的一些数异或出来,那么由原序列的一些数异或出的结果也可以由线性基里的一些数得到。
- 如果 \(d_i\oplus d_j\oplus d_k=0\) ,假设 \(d_k\) 是最后一个被插入的,那么 \(d_k\) 在沿途一定会经过 \(d_i,d_j\),这时候 \(d_k\) 会被削成 \(0\)。
- 明天证wwww
这玩意咋用
其实能干的事情还是挺多的。
序列中子集能异或的最大值
从高位向低位枚举,假如异或上当前的数字会让答案变大,就异或就可以了
我不写了!
撸猫是快乐的!!!!
ABC是好的!!!!!
标签:数字,序列,异或,子集,线性,oplus From: https://www.cnblogs.com/cc0000/p/16939825.html