线性基模板

参考博客

struct L_B {
    LL d[65], p[65];
    int cnt;
    void init() {
        memset(d, 0, sizeof(d));
        memset(p, 0, sizeof(p));
        cnt = 0;
    }  // 1e18以内的数都适用.
    bool Insert(LL val) {
        for (int i = 60 ; i >= 0 ; i --) {
            if (val & (1ll << i)) {
                if (!d[i]) {
                    d[i]=val;
                    break;
                }
                val^=d[i];
            }
        }
        return val > 0;
        // 可判断val是否存在于线性基当中.
    }
    LL query_max() {
        LL res = 0;
        for (int i = 60 ; i >= 0 ; i --) {
            if ((res^d[i]) > res) res ^= d[i];
        }
        return res;
    }
    LL query_min() {  // 应该预先判断能否是0的情况..QAQ
        for (int i = 0 ; i <= 60 ; i ++) {
            if (d[i]) return d[i];
        }
        return 0;
    }
    void rebuild() { // 用于求第k小值.需要先进行独立预处理
        for (int i = 60 ; i >= 0 ; i --) {
            for (int j = i-1 ; j >= 0 ; j --) {
                if (d[i] & (1ll<<j)) d[i] ^= d[j];
            }
        }
        for (int i = 0 ; i <= 60 ; i ++) {
            if (d[i]) p[cnt++]=d[i];
        }
    }
    LL kthquery(LL k) { // 注意判断原序列异或出0的情况, 此时应该将k -- 在进行后面的操作.
        LL res = 0;
        if (k >= (1ll << cnt)) return -1;
        for (int i = 60 ; i >= 0 ; i --) {
            if (k & (1LL<<i)) res ^= p[i];
        }
        return res;
    }
    void Merge(const L_B &b) { // 把b这个线性基插入到当前这个线性基中.
        for (int i = 60 ; i >= 0 ; i --)
            if (b.d[i]) Insert(b.d[i]);
    }
}LB;
View Code
原文地址:https://www.cnblogs.com/qwertiLH/p/9611204.html