結果
| 問題 |
No.184 たのしい排他的論理和(HARD)
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2023-03-15 15:11:15 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 3,565 bytes |
| コンパイル時間 | 201 ms |
| コンパイル使用メモリ | 82,444 KB |
| 実行使用メモリ | 97,852 KB |
| 最終ジャッジ日時 | 2024-09-18 08:45:39 |
| 合計ジャッジ時間 | 5,786 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | WA * 3 |
| other | WA * 34 |
ソースコード
# 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)))