結果
| 問題 |
No.3219 Ruler to Maximize
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-08-01 22:09:47 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 91 ms / 2,000 ms |
| コード長 | 4,489 bytes |
| コンパイル時間 | 255 ms |
| コンパイル使用メモリ | 82,292 KB |
| 実行使用メモリ | 79,532 KB |
| 最終ジャッジ日時 | 2025-08-01 22:09:53 |
| 合計ジャッジ時間 | 3,943 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 32 |
ソースコード
from collections import defaultdict
import sys
import os
from typing import Any, Callable
IS_LOCAL = os.environ.get("LOCAL") == "true"
def debug(*args, sep=" ", end="\n", flush=False) -> None:
if IS_LOCAL:
print(*args, sep=sep, end=end, file=sys.stderr, flush=flush)
def yn(flg: bool) -> bool:
print('Yes' if flg else 'No')
return flg
def gcd(a, b):
a = abs(a); b = abs(b)
if a < b: a, b = b, a
while b > 0:
a, b = b, a % b
return a
def lcm(a, b):
return a * b // gcd(a, b)
class monoid_super:
Base: type # ベースの型
identity: Any # 単位元
combine: Callable[[Any, Any], Any] # モノイド演算
def __init__(self, *args):
if not args:
self.value = self.identity
elif len(args) == 1 and isinstance(args[0], monoid_super):
self.value = args[0].value
else:
raw = args[0] if len(args) == 1 else args
self.value = self.Base(raw)
def __mul__(self, other):
if not isinstance(other, type(self)):
return NotImplemented
new_val = self.combine(self.value, other.value)
return type(self)(new_val)
def __getitem__(self, x):
return self.value[x]
def __iter__(self):
return self.value
def __repr__(self):
return f'{self.value}'
class monoid(monoid_super):
Base = int
identity = 0
@staticmethod
def combine(a, b):
return a | b
class UnionFind_with_Value:
def __init__(self, n) -> None:
self.n = n
self.parents = [-1 for _ in range(n)]
self.value = [monoid() for _ in range(n)]
self.potential = [0 for _ in range(n)]
def find(self, x):
path = []
while self.parents[x] >= 0:
path.append(x)
x = self.parents[x]
p = 0
for y in path[::-1]:
self.parents[y] = x
p += self.potential[y]
self.potential[y] = p
return x
def union(self, x, y, d=0):
self.find(x); self.find(y)
px = self.potential[x]
py = self.potential[y]
x = self.find(x)
y = self.find(y)
if x == y:
return False
d += px - py
if self.parents[x] > self.parents[y]:
x, y = y, x
d *= -1
self.parents[x] += self.parents[y]
self.value[x] *= self.value[y]
self.parents[y] = x
self.value[y] = None
self.potential[y] = d
return True
def apply(self, x, m):
if isinstance(m, monoid):
self.value[self.find(x)] *= m
elif isinstance(m, monoid.Base):
self.value[self.find(x)] *= monoid(m)
else:
NotImplemented
def size(self, x):
return -self.parents[self.find(x)]
def prod(self, x):
return self.value[self.find(x)].value
def same(self, x, y):
return self.find(x) == self.find(y)
def diff(self, x, y):
assert self.same(x, y)
return self.potential[y] - self.potential[x]
def members(self, x):
root = self.find(x)
return [i for i in range(self.n) if self.find(i) == root]
def roots(self):
return [i for i, x in enumerate(self.parents) if x < 0]
def group_count(self):
return len(self.roots())
def all_group_members(self):
group_members = defaultdict(list)
for member in range(self.n):
group_members[self.find(member)].append(member)
return group_members
def __str__(self):
return '\n'.join(
f'{r}: {m} {self.prod(r)}' for r, m in self.all_group_members().items()
)
def main():
readline = sys.stdin.readline
float("inf")
N = int(input())
A = list(map(int, readline().split()))
U = UnionFind_with_Value(N)
for i, a in enumerate(A):
U.apply(i, monoid(a))
for i, a in enumerate(A):
for j in range(i + 1, N):
aa = A[j]
if a & aa > 0:
U.union(i, j)
S = [(U.prod(i), i) for i in U.roots()]
S.sort(reverse=True)
W = S[0][0]
B = sum(s for s, _ in S[1::])
print(W * B)
ans = [None] * N
r = S[0][1]
for i in range(N):
if U.find(i) == r:
ans[i] = 'W'
else:
ans[i] = 'B'
print(''.join(ans))
debug(W, B)
debug(U)
if __name__ == "__main__":
main()