Official

J - XORのXOR/XOR of XOR Editorial by sounansya


各辺が何回総 XOR に寄与するかを考えます。同じ数同士の XOR は \(0\) になることから、ある辺が総 XOR に寄与する回数が偶数なら寄与は \(0\) で、奇数なら寄与はその辺の重みになることが分かります。

ある辺(頂点 \(u,v\) を相互に結んでいるとする)が総 XOR に寄与する回数は、 \(v\) から見た部分木 \(u\) の大きさを \(S_u\)\(u\) から見た部分木 \(v\) の大きさを \(S_v\) とすると \(S_u\times S_v\) と表すことができます。 \(S_u+S_v=N\) が成立することと、 \(S_u\)\(S_v\) のどちらかの一方は頂点 \(1\) を根として考えた根つき木で根からの深さ優先探索を行うことで求めることができます。

以上を適切に実装することでこの問題に正答することができます。計算量は \(O(N)\) 時間です。

実装例(Python3)

import sys
import pypyjit
pypyjit.set_param('max_unroll_recursion=-1')
sys.setrecursionlimit(10**6)
input = sys.stdin.readline
n = int(input())
g = [[] for _ in range(n)]
for i in range(n - 1):
    u, v, c = map(int, input().split())
    u, v = u - 1, v - 1
    g[u].append((v, c))
    g[v].append((u, c))

ans = 0


def dfs(x, fr):
    res = 1
    for u, w in g[x]:
        if u != fr:
            s = dfs(u, x)
            if s % 2 == 1 and (n - s) % 2 == 1:
                global ans
                ans ^= w
            res += s
    return res


dfs(0, -1)
print(ans)

posted:
last update: