线性基模版

cpp
struct LinearBasis {
    static const int MAX_L = 30; // int 范围内最高位到 30 (2^30)
    int p[MAX_L + 1];      // 基础线性基
    int d[MAX_L + 1];      // 用于查询第 k 小的重构基
    int cnt;               // 线性基内元素的个数
    bool has_zero;         // 是否能异或出 0

    LinearBasis() {
        memset(p, 0, sizeof(p));
        memset(d, 0, sizeof(d));
        cnt = 0;
        has_zero = false;
    }

    // 插入一个 int 数值
    bool insert(int x) {
        for (int i = MAX_L; i >= 0; --i) {
            if (!(x >> i)) continue;
            if (!p[i]) {
                p[i] = x;
                cnt++;
                return true;
            }
            x ^= p[i];
        }
        has_zero = true;
        return false;
    }

    // 查询当前集合能异或出的最大值
    int query_max() {
        int res = 0;
        for (int i = MAX_L; i >= 0; --i) {
            res = max(res, res ^ p[i]);
        }
        return res;
    }

    // 查询最小正异或和
    int query_min() {
        if (has_zero) return 0;
        for (int i = 0; i <= MAX_L; ++i) {
            if (p[i]) return p[i];
        }
        return 0;
    }

    // 高斯消元重构,支持查询第 k 小
    void rebuild() {
        cnt = 0;
        for (int i = 0; i <= MAX_L; ++i) d[i] = 0;
        
        // 这一步是关键优化:将线性基转为行最简形
        for (int i = MAX_L; i >= 0; --i) {
            for (int j = i - 1; j >= 0; --j) {
                if ((p[i] >> j) & 1) p[i] ^= p[j];
            }
        }
        for (int i = 0; i <= MAX_L; ++i) {
            if (p[i]) d[cnt++] = p[i];
        }
    }

    // 查询第 k 小值
    int query_kth(int k) {
        if (has_zero) k--; 
        if (k == 0) return 0;
        if (k >= (1 << cnt)) return -1;

        int res = 0;
        for (int i = 0; i < cnt; ++i) {
            if ((k >> i) & 1) res ^= d[i];
        }
        return res;
    }
};
莫队模版
KMP模版