結果
問題 |
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()