05-算法模板/07-线性基:修订间差异
跳转到导航
跳转到搜索
小 导入1个版本 |
小 导入1个版本 |
| (未显示另一用户的1个中间版本) | |
(没有差异)
| |
2026年5月20日 (三) 18:12的最新版本
线性基可以用于处理异或相关问题,如求最大异或和、第 [math]\displaystyle{ k }[/math] 小异或和等。
模板
给定 [math]\displaystyle{ n }[/math] 个整数(数字可能重复),求在这些数中选取任意个,使得它们的异或和最大。
#include <bits/stdc++.h>
using namespace std;
const int MAXL = 50;
struct LinearBasis
{
long long a[MAXL + 1];
LinearBasis()
{
std::fill(a, a + MAXL + 1, 0);
}
LinearBasis(long long *x, int n)
{
build(x, n);
}
void insert(long long t)
{
for (int j = MAXL; j >= 0; j--)
{
if (!t)
return;
if (!(t & (1ll << j)))
continue;
if (a[j])
t ^= a[j];
else
{
for (int k = 0; k < j; k++)
if (t & (1ll << k))
t ^= a[k];
for (int k = j + 1; k <= MAXL; k++)
if (a[k] & (1ll << j))
a[k] ^= t;
a[j] = t;
break;
}
}
}
void build(long long *x, int n)
{
std::fill(a, a + MAXL + 1, 0);
for (int i = 1; i <= n; i++)
insert(x[i]);
}
long long queryMax()
{
long long res = 0;
for (int i = 0; i <= MAXL; i++)
res ^= a[i];
return res;
}
void mergeFrom(const LinearBasis &other)
{
for (int i = 0; i <= MAXL; i++)
insert(other.a[i]);
}
};
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
long long n, x;
cin >> n;
LinearBasis lb;
for (int i = 1; i <= n; i++)
{
cin >> x;
lb.insert(x);
}
cout << lb.queryMax() << "\n";
return 0;
}
使用说明
- insert(x):向线性基中插入一个数 [math]\displaystyle{ x }[/math]
- queryMax():查询能表示出的最大异或和
- mergeFrom(other):合并另一个线性基
时间复杂度:插入 [math]\displaystyle{ O(\log \max) }[/math],查询 [math]\displaystyle{ O(\log \max) }[/math]。