結果
| 問題 |
No.1451 集団登校
|
| コンテスト | |
| ユーザー |
👑 SPD_9X2
|
| 提出日時 | 2021-03-31 15:22:13 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 464 ms / 2,000 ms |
| コード長 | 2,348 bytes |
| コンパイル時間 | 213 ms |
| コンパイル使用メモリ | 82,232 KB |
| 実行使用メモリ | 132,736 KB |
| 最終ジャッジ日時 | 2024-12-14 23:48:12 |
| 合計ジャッジ時間 | 6,883 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 27 |
ソースコード
"""
確率は1/2^N
で表される
ufを使うが…
マージテクを使えばおk
"""
import sys
from sys import stdin
def inverse(a,mod): #aのmodを法にした逆元を返す
return pow(a,mod-2,mod)
mod = 10**9+7
half = inverse(2,mod)
def uf_find(n,p):
ufl = []
while p[n] != n:
ufl.append(n)
n = p[n]
for i in ufl:
p[i] = n
return n
def uf_union(a,b,p,rank,dic):
ap = uf_find(a,p)
bp = uf_find(b,p)
if ap == bp:
return True
else:
if rank[ap] > rank[bp]: #merge ap <- bp
p[bp] = ap
rank[ap] += rank[bp]
elif rank[ap] < rank[bp]:
p[ap] = bp
rank[bp] += rank[ap]
else: #小さい方を大きい方にマージする
if len(dic[ap]) >= len(dic[bp]):
p[bp] = ap
rank[ap] += rank[bp]
for x in dic[bp]:
if x != -1:
if dic[bp][-1]-dic[ap][-1] >= 0:
dic[ap][x] = dic[bp][x] * pow(2,dic[bp][-1]-dic[ap][-1],mod) % mod
else:
dic[ap][x] = dic[bp][x] * pow(half,abs(dic[bp][-1]-dic[ap][-1]),mod) % mod
dic[ap][-1] += 1
else:
ap,bp = bp,ap
p[bp] = ap
rank[ap] += rank[bp]
for x in dic[bp]:
if x != -1:
if dic[bp][-1]-dic[ap][-1] >= 0:
dic[ap][x] = dic[bp][x] * pow(2,dic[bp][-1]-dic[ap][-1],mod) % mod
else:
dic[ap][x] = dic[bp][x] * pow(half,abs(dic[bp][-1]-dic[ap][-1]),mod) % mod
dic[ap][-1] += 1
return False
mod = 10**9+7
N,M = map(int,stdin.readline().split())
p = [i for i in range(N)]
rank = [1] * N
dic = [{} for i in range(N)]
for i in range(N):
dic[i][i] = 1
dic[i][-1] = 0
for i in range(M):
a,b = map(int,stdin.readline().split())
a -= 1
b -= 1
uf_union(a,b,p,rank,dic)
#print (dic[0])
ans = [0] * N
for i in range(N):
if uf_find(i,p) == i:
for x in dic[i]:
if x != -1:
ans[x] += inverse(dic[i][x] * pow(2,dic[i][-1],mod),mod)
print ("\n".join(map(str,ans)))
SPD_9X2