結果
問題 | No.2504 NOT Path Painting |
ユーザー | suisen |
提出日時 | 2023-02-21 08:47:46 |
言語 | PyPy3 (7.3.15) |
結果 |
RE
|
実行時間 | - |
コード長 | 3,245 bytes |
コンパイル時間 | 488 ms |
コンパイル使用メモリ | 82,444 KB |
実行使用メモリ | 72,040 KB |
最終ジャッジ日時 | 2024-12-15 16:29:35 |
合計ジャッジ時間 | 4,428 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | RE | - |
testcase_01 | RE | - |
testcase_02 | RE | - |
testcase_03 | RE | - |
testcase_04 | RE | - |
testcase_05 | RE | - |
testcase_06 | RE | - |
testcase_07 | RE | - |
testcase_08 | RE | - |
testcase_09 | RE | - |
testcase_10 | RE | - |
testcase_11 | RE | - |
testcase_12 | RE | - |
testcase_13 | RE | - |
testcase_14 | RE | - |
testcase_15 | RE | - |
testcase_16 | RE | - |
testcase_17 | RE | - |
testcase_18 | RE | - |
testcase_19 | RE | - |
testcase_20 | RE | - |
ソースコード
import functools import operator from collections import deque from typing import List P = 998244353 def inv(n): # return 1 / n return pow(n, P - 2, P) def add(*args): # return sum(args) return sum(args) % P def mul(*args): # return functools.reduce(operator.mul, args, 1) res = 1 for v in args: res = res * v % P return res def edge_num(n: int): return (n * (n + 1)) >> 1 def solve(n: int, g: List[List[int]]): m = edge_num(n) inv_m = inv(m) par_ = [0] * n siz_ = [1] * n def precalc(u: int, p: int): par_[u] = p for v in g[u]: if v != p: siz_[u] += precalc(v, u) return siz_[u] precalc(0, -1) def subtree_size(u: int, p: int): if par_[u] == p: return siz_[u] else: return n - siz_[p] def calc_t_1(u: int, ng1: int): return n - subtree_size(ng1, u) def calc_t_2(u: int, ng1: int, ng2: int): return n - subtree_size(ng1, u) - subtree_size(ng2, u) ans_f = [0] * n for x in range(n): u_x = m - sum(edge_num(subtree_size(y, x)) for y in g[x]) ans_f[x] = mul(m, inv(m - u_x)) ans_g = [[0] * n for _ in range(n)] par = [[-1] * n for _ in range(n)] # x, y, A, B dq = deque() for x in range(n): u_x = edge_num(n) - sum(edge_num(subtree_size(y, x)) for y in g[x]) for y in g[x]: s_y = subtree_size(y, x) par[x][y] = x dq.append((x, y, mul(u_x - s_y * (n - s_y), ans_f[x]), 0)) while dq: x, z, A, B = dq.popleft() par_z = par[x][z] s_z = subtree_size(z, par_z) u_z = edge_num(s_z) - sum(edge_num(subtree_size(y, z)) for y in g[z] if y != par_z) t_z = s_z ans_g[x][z] = add(A, mul(u_z, ans_f[z]), B) prev_z2, z2 = z, par_z while z2 != x: next_z2 = par[x][z2] t_z2 = calc_t_2(z2, prev_z2, next_z2) ans_g[x][z] = add(ans_g[x][z], mul(t_z, t_z2, ans_g[z][z2])) prev_z2, z2 = z2, next_z2 t_x = calc_t_1(x, prev_z2) ans_g[x][z] = add(1, mul(ans_g[x][z], inv_m)) ans_g[x][z] = mul(ans_g[x][z], inv(1 - mul(t_x, t_z, inv_m))) for y in g[z]: if y == par_z: continue s_y = subtree_size(y, z) next_t_z = t_z - s_y next_A = add(A, mul(u_z - s_y * (s_z - s_y), ans_f[z])) next_B = add(B, mul(next_t_z, t_x, ans_g[x][z])) prev_z2, z2 = z, par_z while z2 != x: next_z2 = par[x][z2] t_z2 = calc_t_2(z2, prev_z2, next_z2) next_B = add(next_B, mul(next_t_z, t_z2, ans_g[z][z2])) prev_z2, z2 = z2, next_z2 par[x][y] = z dq.append((x, y, next_A, next_B)) ans = 1 for x in range(n): ans = add(ans, mul(ans_f[x], inv_m)) for y in range(x): ans = add(ans, mul(ans_g[x][y], inv_m)) print(ans) n = int(input()) g = [[] for _ in range(n)] for _ in range(n - 1): u, v = map(int, input().split()) u -= 1 v -= 1 g[u].append(v) g[v].append(u) solve(n, g)