数论-线性基

线性基基基基基

(k) 小异或的高斯消元方法不是很懂,可能暂时也没功夫去学了,先来一发可以感性理解的线性基板子。

从高位到低位贪心。

性质:

  1. 基向量 (p_i) 的第 (i) 位是 (1) ,且是最高位。
  2. 用基向量构造其他向量的方法唯一。
  3. 无法构造 0 。

求向量组 (a) 的线性基 (p)

    for (int i = 1; i <= N; ++i) {
        for (int j = 62; j >= 0; --j)
            if ((A[i]) >> j) & 1) {
                if (!P[j]) {
                    P[j] = A[i];
                    break;
                }
                A[i] ^= P[j];
            }
    }

求最大值

    int mx = 0;
    for (int i = 62; i >= 0; --i)
        if ((mx ^ P[i]) > mx)
            mx ^= P[i];

求最小值

就是 (p_0)

(k) 小异或值

构造只有 (p_i) 的第 (i) 位为 (1) 的线性基。据说如果新的线性基大小(非 (0) 向量个数)等于原线性基,则仍然无法构造 (0) ,否则可以。

    for (int i = 62; i >= 0; --i) {
        for (int j = i - 1; j >= 0; --j)
        if ((P[i] >> j) & 1)
            P[i] ^= P[j];
    }
    int x = -1;
    for (int i = 0; i <= 62; ++i)
        if (P[i])
            P[++x] = P[i];
    }

上面的构造完成之后,就可以求 (a) 的第 (k) 小异或值了。

    for (int i = 62; i >= 0; --i)
        if ((k >> i) & 1)
            ans ^= P[i];

判断向量是否能被构造

    for (int i = 62; i >= 0; --i)
        if ((x >> i) & 1)
            x ^= P[i];
    if (!x)
        suc = 1;
原文地址:https://www.cnblogs.com/ghcred/p/10491468.html