线性基

 

vector<ull> B;
void insert(ull x) {
    for (auto b : B)
        x = min(x, b ^ x);
    for (auto &b : B)
        b = min(b, b ^ x);
    if (x)
        B.push_back(x);
}
构造代码

这样构造产生的性质:

  • 产生的线性基可以表示原集里面xor产生的所有值
  • 线性基里面的值不能被其他元素xor产生
  • 每个元素的最高有效位各不相同,
  • 如果某一位是一个元素的最高有效位,则其他元素在这一位均为 
  • 判断某个值是否可以产生, 就这个值去 假的insert一下 看他是不是0即可
  • 第K大的xor值 直接 对线性基排一个序列 ,然后二进制那个求就行了
  • 如果构造的线性基比原集合小,说明原集合可以异或出 0 ,那么我们需要将 K 减去 1 。
  •  

sort(B.begin(), B.end());
ull ans = 0;
if (B.size() < n)
    k--;
for (auto b : B) {
    if (k & 1)
        ans ^= b;
    k >>= 1;
}
if (k == 0)
    cout << ans << endl;
else
    cout << -1 << endl;
第K大xor数
  • 线性基的交集,没有看懂
inline bool insert(ll x)
{
    for (int i=62;i>=0;i--)
        if (x>>i)//为什么可以不写x&(1<<i)?,因为我们每次x的最高位都是因为x^=p[i]变为0,这样也能判断最高位
            if (p[i])
                x^=p[i];//如果第i位这个线性基有,同上方的p[6]
            else
            {
                p[i]=x;
                return 1;//1代表插入成功
            }
    return 0; //0代表这个数x能被线性基表示,0需要特判
}

LinearBasis Merge(LinearBasis A,LinearBasis B) {
    LinearBasis All , C , D;
    All.clear();
    C.clear();
    D.clear();
    for (int i = 60;i >= 0;i--) {
        All.basis[i] = A.basis[i];
        D.basis[i] = 1ll << i;
    }
    for (int i = 60; i >= 0; i--) {
        if (B.basis[i]) {
            ll v = B.basis[i] , k = 0;
            bool can = true;
            for (int j = 60; j >= 0; j--) {
                if (v & (1ll << j)) {
                    if (All.basis[j]) {
                        v ^= All.basis[j];
                        k ^= D.basis[j];
                    } else {
                        can = false;
                        All.basis[j] = v;
                        D.basis[j] = k;
                        break;
                    }
                }
            }

            if (can) {
                ll v = 0;
                for (int j = 60; j >= 0; j--) {
                    if (k & (1ll << j)) {
                        v ^= A.basis[j];
                    }
                }
                C.insert(v);
            }
        }
    }
    C.build();
    return C;
}
线性基求交

 

posted @ 2023-04-18 18:54  VxiaohuanV  阅读(15)  评论(0编辑  收藏  举报