結果

問題 No.184 たのしい排他的論理和(HARD)
ユーザー 草苺奶昔草苺奶昔
提出日時 2023-03-15 15:11:15
言語 PyPy3
(7.3.15)
結果
WA  
実行時間 -
コード長 3,565 bytes
コンパイル時間 167 ms
コンパイル使用メモリ 81,644 KB
実行使用メモリ 96,728 KB
最終ジャッジ日時 2023-10-18 12:24:40
合計ジャッジ時間 7,047 ms
ジャッジサーバーID
(参考情報)
judge15 / judge12
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 WA -
testcase_01 WA -
testcase_02 WA -
testcase_03 WA -
testcase_04 WA -
testcase_05 WA -
testcase_06 WA -
testcase_07 WA -
testcase_08 WA -
testcase_09 WA -
testcase_10 WA -
testcase_11 WA -
testcase_12 WA -
testcase_13 WA -
testcase_14 WA -
testcase_15 WA -
testcase_16 WA -
testcase_17 WA -
testcase_18 WA -
testcase_19 WA -
testcase_20 WA -
testcase_21 WA -
testcase_22 WA -
testcase_23 WA -
testcase_24 WA -
testcase_25 WA -
testcase_26 WA -
testcase_27 WA -
testcase_28 WA -
testcase_29 WA -
testcase_30 WA -
testcase_31 WA -
testcase_32 WA -
testcase_33 WA -
testcase_34 WA -
testcase_35 WA -
testcase_36 WA -
権限があれば一括ダウンロードができます

ソースコード

diff #

# https://maspypy.github.io/library/linalg/xor/vector_space.hpp
# 可合并的线性基
from typing import List, Optional


class VectorSpace:
    @staticmethod
    def merge(v1: "VectorSpace", v2: "VectorSpace") -> "VectorSpace":
        """合并两个线性基, 返回合并后的线性基(注意会修改原有的线性基)."""
        if len(v1) < len(v2):
            v1, v2 = v2, v1
        for v in v2._data:
            v1.add(v)
        return v1

    @staticmethod
    def intersection(v1: "VectorSpace", v2: "VectorSpace", maxDim: int) -> "VectorSpace":
        """求两个线性基的交集, 返回交集的线性基(注意会修改原有的线性基)."""
        x = v1._orthogonalSpace(maxDim)
        y = v2._orthogonalSpace(maxDim)
        x = VectorSpace.merge(x, y)
        return x._orthogonalSpace(maxDim)

    __slots__ = ("_data",)

    def __init__(self, nums: Optional[List[int]] = None) -> None:
        self._data = []
        if nums is not None:
            for v in nums:
                self.add(v)

    def add(self, v: int) -> bool:
        for e in self._data:
            if e == 0 or v == 0:
                break
            v = min(v, v ^ e)
        if v:
            self._data.append(v)
            return True
        return False

    def getMax(self, xorVal=0) -> int:
        res = xorVal
        for e in self._data:
            res = max(res, res ^ e)
        return res

    def getMin(self, xorVal=0) -> int:
        res = xorVal
        for e in self._data:
            res = min(res, res ^ e)
        return res

    def _orthogonalSpace(self, maxDim: int) -> "VectorSpace":
        self._normalize()
        m = maxDim
        tmp = [0] * m
        for e in self._data:
            tmp[e.bit_length() - 1] = e
        tmp = transpose(m, m, tmp, inplace=True)
        res = VectorSpace()
        for j in range(m):
            if tmp[j] & (1 << j):
                continue
            res.add(tmp[j] | (1 << j))
        return res

    def _normalize(self, reverse=True) -> None:
        n = len(self._data)
        for j in range(n):
            for i in range(j):
                self._data[i] = min(self._data[i], self._data[i] ^ self._data[j])
        self._data.sort(reverse=reverse)

    def __len__(self) -> int:
        return len(self._data)

    def __contains__(self, v: int) -> bool:
        for e in self._data:
            if v == 0:
                break
            v = min(v, v ^ e)
        return v == 0


def transpose(row: int, col: int, matrix1D: List[int], inplace=False) -> List[int]:
    """矩阵转置

    matrix1D:每个元素是状压的数字
    inplace:是否修改原矩阵
    """
    assert row == len(matrix1D)
    m = matrix1D[:] if not inplace else matrix1D
    log = 0
    max_ = max(row, col)
    while (1 << log) < max_:
        log += 1
    if len(m) < (1 << log):
        m += [0] * ((1 << log) - len(m))
    w = 1 << log
    mask = 1
    for i in range(log):
        mask = mask | (mask << (1 << i))
    for t in range(log):
        w >>= 1
        mask = mask ^ (mask >> w)
        for i in range(1 << t):
            for j in range(w):
                m[w * 2 * i + j] = ((m[w * (2 * i + 1) + j] << w) & mask) ^ m[w * 2 * i + j]
                m[w * (2 * i + 1) + j] = ((m[w * 2 * i + j] & mask) >> w) ^ m[w * (2 * i + 1) + j]
                m[w * 2 * i + j] = ((m[w * (2 * i + 1) + j] << w) & mask) ^ m[w * 2 * i + j]
    return m[:col]


if __name__ == "__main__":
    n = int(input())
    nums = list(map(int, input().split()))
    print(len(VectorSpace(nums)))
0