线性基学习笔记

lmrttx

2021-01-12 21:11:29

Personal

线性基解决的问题: >给定n个整数(数字可能重复),求在这些数中选取任意个,使得他们的异或和最大。 线性基是一个数列。 有原数列:$a_1$,$a_2$...$a_n$,则它对应的线性基记为:$p_1$,$p_2$...$p_n$。 注意:线性基是一个数组。 ~~为什么叫这奇怪的名字...~~ $p_i$的意义就是:**出现1的最高位为$i$的数,当然是在二进制的表示下。** 对于每个数,找出它最高位的1(在第 $i$ 位),从而得到$p_i$。 如果$p_i$为0,就加入线性基。 否则异或 $p_i$ 继续寻找。 在 $p$ 数组搞完后,**从高位往低位**,如果异或后答案变大,就异或,不然跳过。 得到最终答案。 不想证明。 [洛谷线性基模板](https://www.luogu.com.cn/problem/P3812),代码: ```cpp #include<bits/stdc++.h> using namespace std; #define N 55 #define ll long long ll n,ans,a[N],p[2*N]; void get(ll x){ for(int i=62;i>=0;i--){ if(!(x>>(ll)i))continue; if(!p[i]){p[i]=x;break;} x^=p[i]; } } int main(){ scanf("%lld",&n); for(register ll i=1;i<=n;i++) {scanf("%lld",&a[i]);get(a[i]);} for(int i=62;i>=0;i--){ if((ans^p[i])>ans)ans=ans^p[i]; } printf("%lld",ans); return 0; } ``` 谢谢阅读。