線性基
線性基是一個可以在 \(\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];
}
};
