深夜蚊子多脑洞大,想想好像在数电课上翻(摸)阅(鱼)的线性基也就那样
抛开向量空间线性空间运算规则合法性组合张成极小生成集极大线性无关集BLABLA来说,
线性基就是一个能生成原数组中任意异或组合的最小集合(0除外)
暴力测试如下,十分OK (由于不断切换IDE导致排版缩进惨不忍睹)
https://paste.ubuntu.com/p/c4HZcTYXYh/
其框架如下,可以说是设计的十分精妙了
void cal(){
rep(i,1,n){
rrep(j,30,0){
if(a[i]>>j&1){
if(b[j]) a[i]^=b[j];
else{
b[j]=a[i];
rrep(k,j-1,0) if(b[k]&&(b[j]>>k&1))b[j]^=b[k];
rep(k,j+1,30) if(b[k]>>j&1) b[k]^=b[j];
break;
}
}
}
}
}
对于\(b[j]\),若\(b[j]=1\),则说明原数组当中至少存在一个数,其最高位为1,因此最终至少会维护成一个上三角型的矩阵
rrep(k,j-1,0) if(b[k]&&(b[j]>>k&1))b[j]^=b[k];
这一段是为了维护\(b[j]\)的最简形式(或者说,维护线性无关),若更低位\(b[k]=1\),且\(b[j]\)的\(k\)位也为1,能证明\(b[j]\)必然不是最简形式,与其异或至少\(b[j]\)的\(k\)位会置0,甚至其它相同的位也会置0,而在此之前\(b[k]\)与\(b[k-1...0]\)都是线性无关,所以异或是不会损失最优解的,因此\(b[j]\)此时也是与\(b[k...0]\)线性无关
也正因如此
if(b[j]) a[i]^=b[j];
这一段对于每个\(a[i]\),首先需要的就是剔除已经存在于基中的位,而每一个\(b[]\)都是线性无关的,那么肯定不会出现在前面一部分非\(b[j]\)的\(k\)位把它异或位0后接下来的\(b[j']\)的\(k\)位又异或回1的情况
那么接下来
rep(k,j+1,30) if(b[k]>>j&1) b[k]^=b[j];
既然都线性无关了那当然要把高位的存在线性相关的也要异或一下
PS.可以直接理解成先用下行消去自己,再用自己消去上行
那么通过2个现象:
1.对于\(b[j]\),若\(b[j]=1\),则说明原数组当中至少存在一个数,其最高位为1
2.\(b[]\)的维护是线性无关的
可以YY得出:
对于线性基中存在的某一位\(i\),有且只有一个\(b[j]\)在该位为1
在此基础上就可以对异或进行为所欲为的操作
Q:基是否唯一确定,也就是问对于相同元素组成但不同顺序的数组,生成的基是否相同?如果唯一确定,那么它所拥有的性质是什么
虽然没有暴力测试与高端的证明,但直觉上认为基是相同的,因为基与数本身顺序无直接关系至于位的加入顺序相关,而为了维护线性无关那它应当是唯一的,性质emmm不知道
PS.话说线性空间的基不是随便挑的吗..
//暴力测试通过猜想成立,证明去tm的
有了极为肤浅的认识后那接下来就是切题的事情了
后记:编辑完发现都快2点半了,猝死度++