結果

問題 No.184 たのしい排他的論理和(HARD)
ユーザー 草苺奶昔草苺奶昔
提出日時 2023-03-15 15:11:30
言語 PyPy3
(7.3.15)
結果
AC  
実行時間 173 ms / 5,000 ms
コード長 3,506 bytes
コンパイル時間 156 ms
コンパイル使用メモリ 82,048 KB
実行使用メモリ 97,428 KB
最終ジャッジ日時 2024-09-18 08:45:46
合計ジャッジ時間 5,447 ms
ジャッジサーバーID
(参考情報)
judge3 / judge4
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 57 ms
69,456 KB
testcase_01 AC 54 ms
68,080 KB
testcase_02 AC 55 ms
69,032 KB
testcase_03 AC 56 ms
67,968 KB
testcase_04 AC 56 ms
68,720 KB
testcase_05 AC 56 ms
67,852 KB
testcase_06 AC 55 ms
68,468 KB
testcase_07 AC 57 ms
67,804 KB
testcase_08 AC 144 ms
89,928 KB
testcase_09 AC 86 ms
79,396 KB
testcase_10 AC 120 ms
85,364 KB
testcase_11 AC 105 ms
83,044 KB
testcase_12 AC 148 ms
94,568 KB
testcase_13 AC 164 ms
94,996 KB
testcase_14 AC 123 ms
85,680 KB
testcase_15 AC 165 ms
97,324 KB
testcase_16 AC 144 ms
92,600 KB
testcase_17 AC 157 ms
94,748 KB
testcase_18 AC 57 ms
68,636 KB
testcase_19 AC 55 ms
67,652 KB
testcase_20 AC 87 ms
90,200 KB
testcase_21 AC 163 ms
97,192 KB
testcase_22 AC 172 ms
97,184 KB
testcase_23 AC 59 ms
69,100 KB
testcase_24 AC 59 ms
69,732 KB
testcase_25 AC 57 ms
69,560 KB
testcase_26 AC 57 ms
67,708 KB
testcase_27 AC 55 ms
67,840 KB
testcase_28 AC 125 ms
87,084 KB
testcase_29 AC 155 ms
94,640 KB
testcase_30 AC 139 ms
91,940 KB
testcase_31 AC 131 ms
88,848 KB
testcase_32 AC 146 ms
92,756 KB
testcase_33 AC 162 ms
96,824 KB
testcase_34 AC 160 ms
97,428 KB
testcase_35 AC 171 ms
97,128 KB
testcase_36 AC 173 ms
97,308 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

# 可合并的线性基
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(2 ** len(VectorSpace(nums)))
0