XOR 基底

整数を $\mathbb{F}_2$ 上のベクトルとみなし、掃き出し法で最上位ビットが互いに異なる基底を持ちます。いくつかを選んで XOR したときに作れる値の集合が分かります。

ここで $A$ は値の最大値です。

コード

class XorBasis:
    def __init__(self):
        self.basis = []  # どの 2 つも最上位ビットが異なる

    def add(self, x):
        # x を加える。x が今の基底の XOR で作れなかったら True
        for b in self.basis:
            x = min(x, x ^ b)
        if x == 0:
            return False
        self.basis.append(x)
        return True

    def can_make(self, x):
        # x が基底のいくつかの XOR で作れるか(何も選ばないと 0)
        for b in self.basis:
            x = min(x, x ^ b)
        return x == 0

    def max_xor(self, x=0):
        # x に基底のいくつかを XOR してできる最大値
        for b in sorted(self.basis, reverse=True):
            x = max(x, x ^ b)
        return x

    def __len__(self):
        return len(self.basis)