def solve(N, CS):
sums = [sum(row) for row in CS]
m = min(sums)
if any((x - m) % N for x in sums):
return ()
AS = [(x - m) // N for x in sums]
BS = [x - AS[0] for x in CS[0]]
if any(x < 0 for x in BS):
return ()
NCS = [tuple(AS[i] + BS[j] for j in range(N)) for i in range(N)]
if NCS != CS:
return ()
return (AS, BS)
def blute(N,M,edges,edgelist):
ret = [0] * (N + 1)
for i in range(2 ** M):
deg = [0] * N
for j in range(M):
if i & (1 << j):
a, b = edgelist[j]
deg[a] += 1
deg[b] += 1
r = sum(x % 2 for x in deg)
ret[r] += 1
return ret
観察してわかったこと
連結でない場合はそれぞれを求めて畳み込み
実装
UnionFindで連結成分の頂点と辺の数を数える
逆数・階乗テーブルを作って置いて連結成分ごとに計算
それぞれを畳み込み
結果TLE
コンテスト後AC
TLEの原因: 畳み込みの計算にFFTライブラリを使ったこと
素朴なループで畳み込めばACだった
py
def solve(N,M,edges,edgelist):
init_unionfind(N)
for x, y in edgelist:
unite(x, y)
comps = []
for x in range(N):
if find_root(x) == x:
comps.append((num_edges[x], num_vertex[x]))
MOD = 998_244_353
comb = CombinationTable(N + 10, MOD).comb
ret = None
for e, v in comps:
xs = [0] * (v + 1)
xs[0] = 1
for i in range(1, (v // 2) + 1):
xs[i * 2] = comb(v, 2 * i)
if e > v - 1:
m = pow(2, e - (v - 1), MOD)
xs = [x * m % MOD for x in xs]
if ret is None:
ret = xs
else:
ys = ret
ret = [0] * (len(xs) + len(ys) - 1)
for i in range(len(xs)):
for j in range(len(ys)):
ret[i + j] += xs[i] * ys[j]
ret[i + j] %= MOD
return ret