結果
問題 |
No.3025 Chocol∀te
|
ユーザー |
|
提出日時 | 2025-02-14 21:47:43 |
言語 | Python3 (3.13.1 + numpy 2.2.1 + scipy 1.14.1) |
結果 |
TLE
|
実行時間 | - |
コード長 | 3,632 bytes |
コンパイル時間 | 202 ms |
コンパイル使用メモリ | 12,544 KB |
実行使用メモリ | 206,700 KB |
最終ジャッジ日時 | 2025-02-14 21:49:09 |
合計ジャッジ時間 | 57,013 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 74 TLE * 3 |
ソースコード
import sys, math def main(): data = sys.stdin.buffer.read().split() if not data: return it = iter(data) N = int(next(it)) M = int(next(it)) # グラフは1-indexed。各頂点 v の隣接集合 adj = [set() for _ in range(N+1)] for _ in range(M): u = int(next(it)) v = int(next(it)) adj[u].add(v) adj[v].add(u) # 各頂点の重み A[1..N] A = [0]*(N+1) for i in range(1, N+1): A[i] = int(next(it)) Q = int(next(it)) # heavy判定の閾値 TH: 初期辺数からおおよそ sqrt(2*M) 程度 TH = int(math.sqrt(2*M)) + 1 # heavy[v] True なら頂点 v は heavy とする heavy = [False]*(N+1) # heavy_sum[v]: 頂点 v が heavy なら、その隣接頂点の重み和を保持 heavy_sum = [0]*(N+1) # heavy_nbr[v]: 頂点 v の隣接頂点のうち heavy なものの集合 heavy_nbr = [set() for _ in range(N+1)] # 初期 heavy 判定(動的に heavy への昇格は一度だけ) for v in range(1, N+1): if len(adj[v]) >= TH: heavy[v] = True # heavy 頂点について heavy_sum と heavy_nbr を初期化 for v in range(1, N+1): if heavy[v]: heavy_sum[v] = sum(A[w] for w in adj[v]) for w in adj[v]: heavy_nbr[w].add(v) out_lines = [] for _ in range(Q): t = int(next(it)) if t == 1: # クエリ1: 辺の追加/削除 u = int(next(it)) v = int(next(it)) if v in adj[u]: # 辺 (u,v) が存在 → 削除 adj[u].remove(v) adj[v].remove(u) if heavy[u]: heavy_sum[u] -= A[v] if heavy[v]: heavy_sum[v] -= A[u] if heavy[v]: heavy_nbr[u].discard(v) if heavy[u]: heavy_nbr[v].discard(u) else: # 辺追加 adj[u].add(v) adj[v].add(u) if heavy[u]: heavy_sum[u] += A[v] if heavy[v]: heavy_sum[v] += A[u] if heavy[v]: heavy_nbr[u].add(v) if heavy[u]: heavy_nbr[v].add(u) # 辺追加後、もし u または v が light で次数が閾値に達したなら heavy へ昇格 for w in (u, v): if not heavy[w] and len(adj[w]) >= TH: heavy[w] = True s = 0 for nb in adj[w]: s += A[nb] heavy_sum[w] = s for nb in adj[w]: heavy_nbr[nb].add(w) elif t == 2: # クエリ2: 頂点 p の重みを a に更新 p = int(next(it)) a = int(next(it)) diff = a - A[p] A[p] = a # p を隣接する heavy 頂点について、heavy_sum を更新 for h in heavy_nbr[p]: heavy_sum[h] += diff else: # クエリ3: 頂点 c の隣接頂点の重み和を出力 c = int(next(it)) if heavy[c]: out_lines.append(str(heavy_sum[c])) else: s = 0 for w in adj[c]: s += A[w] out_lines.append(str(s)) sys.stdout.write("\n".join(out_lines) + "\n") if __name__ == '__main__': main()