0%

线性基

线性基 - OI Wiki (oi-wiki.org)

【模板】线性基 - 洛谷

Idea

易知给出的正整数和它们任意异或后的所有结果和 00 组成的集合 GG 关于异或运算封闭,且为有限集合,满足结合律,有单位元和逆元。所以 GG 构成一个群。我们求的线性基是这个群的最小线性基,即 GG 中的所有元素均可被基中的元素线性表出。

构造线性基的方法详见 insert 函数。

要找到 GG 中最大的异或和,就在线性基中由高位到低位尝试异或出最大的结果,贪心可得。

查询某数是否可被 GG 中元素异或得到,也是在线性基中尝试从高位到低位构建。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const ll N = 1e5 + 10;

ll p[N], n, a[N], ans;

void insert(ll x)
{
for (int i = 63; ~i; i--) {
if (!(x >> i))
continue;
if (!p[i]) {
p[i] = x;
return;
} else
x ^= p[i];
}
}

int main()
{
scanf("%lld", &n);
for (int i = 1; i <= n; i++) {
scanf("%lld", &a[i]);
insert(a[i]);
}
for (int i = 63; ~i; i--)
ans = max(ans, ans ^ p[i]);
printf("%lld", ans);
return 0;
}