写在前面
打多校的时候碰到线性基没学过,于是学一下,然后是笔记,与这个题目的AC代码(参考jiangly)
线性基的所有博客和书籍里,我看到的《算法竞赛》(罗勇军)那本才看懂了,水题也切得非常顺快,推荐
其他博客我是啥也没懂
抑或空间线性基
ll P[63];
bool insert(ll x){
for(int i=62;i>=0;--i){
if(x >> i & 1){
if(!P[i]) {P[i]=x;return false;}
else x ^= P[i];
}
}
return true;
}
ll ask(){
ll res = 0;
for(int i=62;i>=0;--i)res = max(res,res^P[i]);
return res;
}
线性基的概念
思路:将 2^n 种组合空间压缩成 2^m 种组合求抑或
- 线性基是一个序列,任何一个序列都能生成线性基,定义原序列为A,线性基为P
- 原序列中的任何一个元素都能通过线性基中任意元素抑或得到
线性基的性质
- 等价性:在A上进行抑或运算与在P上进行抑或运算结果相同
- 最小性:P中元素个数最少,任意元素组合满足线性无关性,即不存在P中两个组合抑或结果相等的情况
- 线性基中不存在抑或和为0的子集
线性基的构造
规则:P中每个元素的二进制位数(位数不是1的个数)不同,P能组合出的抑或和有$2^k - 1$种,其中,k是P的元素个数
- 所有元素位数不同时,A可以就是P,P也可是其他抑或空间,比如 $A = {1,3,9},P = {1,3,9}、{1,2,9}、{1,2,8}...$
- 存在相同位数的元素时,P可以通过一个代表元,与其他元素的抑或共同组成,比如$A = {a_1,a_2,a_3},Cnt_{a_1} = Cnt_{a_2} = Cnt_{a_3},则 P = {a_1,{a_1} \oplus {a_2}, {a_1} \oplus {a_3}}$
线性基的应用
- 搜一些位置,要求剩下位置不相邻就是线性基
- 最小抑或和,最大抑或和,第k大/小抑或和
最大抑或和
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,x,p[63];
void insert(ll x){
for(int i=62;i>=0;--i){
if(x >> i & 1) {
if(p[i] == 0) {p[i] = x;return;}
else x ^= p[i];
}
}
}
ll ask(){
ll res = 0;
for(int i=6 2;i>=0;--i) res = max(res, res ^ p[i]);
return res;
}
int main(){
cin>>n;
for(int i=1;i<=n;++i){
cin>>x;insert(x);
}
cout<<ask()<<'\n';
return 0;
}
2025杭电多校2 1012
题意:
序列中选择不相邻数字的最大抑或和(n<=50)
思路:
dfs + 线性基
点击查看代码
/* 选/不选dfs生成所有子序列,因为是所有子序列,所以将目前选到的线性基复制一份放到后面去 */void solve(){
cin>>n;
for(int i=1;i<=n;++i) cin>>num[i];
auto insert = [&](vector
for(int i=62;i>=0;--i){
if(x >> i & 1){
if(!P[i]) {P[i] = x;return;}
else x^=P[i];
}
}
};
auto ask = [&](vector<ll> P)->ll{
ll res = 0;
for(int i=62;i>=0;--i) chkmax(res,res^P[i]);
return res;
};
ll ans = 0;
auto dfs = [&](auto && self, int i, vector<ll> P)->void{
if(i >= n+1){
chkmax(ans,ask(P));
return;
}
//不选a[i],选a[i+1], 下一个选[i+3]
if(i + 1 <= n){
auto Q = P;
insert(Q,num[i+1]); //这里必须选择,然后放到线性基中,是多个子序列,所以是复制一份生成更多的子序列
self(self,i+3, move(Q));
}
//选到了第i个数字,下一个选i+2,线性基(构成的序列是P)
insert(P, num[i]);
self(self, i+2, move(P));
};
dfs(dfs,1,vector<ll>(63));
cout<<ans<<'\n';
}

浙公网安备 33010602011771号