线性基
线性基是一个可以在 \(\log\) 的时间复杂度内高效处理子集异或问题的数据结构。
准确来说,对于一个集合 \(S\) ,其最大元素为 \(S_{max}\) ,那么 \(S\) 有一个长度为 \(\lceil\log_2 S_{max}\rceil\) 的线性基。
设原集合 \(S\) 的线性基为 \(A\)
定义: \(A_i\) 是出现 1 的最高位在第 \(i\) 位的数。
性质 1: \(S\) 中若干个任意数的异或和均能被表示成 \(A\) 中一些元素的异或和。
性质 2: \(A\) 是满足性质 1 的最小集合。
性质 3: \(A\) 中没有异或和为 0 的子集。这意味着其异或集合中每个元素的异或方案唯一。
性质 4: \(S\) 与 \(A\) 值域相同。
性质 5: \(A\) 中元素二进制最高位互不相同。
代码
暂时只实现了线性基的部分功能(待填坑)
class LinearBasis {
private:
long long a[65];
const static int maxbit = 63;
public:
bool insert(long long x) {
for (int i=maxbit; i>=0; --i) {
if (x >> i) {
if (a[i]) x ^= a[i];
else return a[i] = x, true;
}
} return false;
}
void merge(const LinearBasis& xx) {
for (int i=maxbit; i>=0; --i)
if(xx.a[i]) insert(xx.a[i]);
}
bool check(long long x) const {
for (int i=maxbit; i>=0; --i) {
if (x >> i) {
if (a[i]) x ^= a[i];
else return true;
}
} return false;
}
long long max() const {
long long res = 0LL;
for (int i=maxbit; i>=0; --i)
if ((res ^ a[i]) > res)
res ^= a[i];
return res;
}
long long min() const {
for (int i=0; i<=maxbit; ++i)
if (a[i]) return a[i];
}
};