結果
| 問題 | No.2588 Increasing Record | 
| コンテスト | |
| ユーザー | 👑  SPD_9X2 | 
| 提出日時 | 2023-11-24 03:53:54 | 
| 言語 | PyPy3 (7.3.15) | 
| 結果 | 
                                WA
                                 
                             | 
| 実行時間 | - | 
| コード長 | 2,512 bytes | 
| コンパイル時間 | 502 ms | 
| コンパイル使用メモリ | 82,420 KB | 
| 実行使用メモリ | 245,944 KB | 
| 最終ジャッジ日時 | 2024-09-27 06:38:32 | 
| 合計ジャッジ時間 | 28,114 ms | 
| ジャッジサーバーID (参考情報) | judge5 / judge4 | 
(要ログイン)
| ファイルパターン | 結果 | 
|---|---|
| sample | AC * 3 | 
| other | AC * 15 WA * 29 | 
ソースコード
"""
連結成分ごとに場合の数を持っておけばいい?
違うな…
dp[v] = vで終わっているrecordの数
dp2[v] = 頂点vに居るときのrecordの数
新しい頂点vを追加する時…
繋がっている連結成分の頂点uに関して、u以上で終わっているrecordの数の合計を出せばok?
mergeと全体加算?
------提出後更新------
4 4
1 3
3 2
1 4
2 4
がだめでした
大きい方じゃなくて、小さい方の和を持っておくといける?
    
???
もしかして部分永続ufが必要ですか??
"""
import sys
from sys import stdin
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):
    ap = uf_find(a,p)
    bp = uf_find(b,p)
    if ap == bp:
        return True
    else:
        #print (dp2,"start",foot)
        if size[ap] > size[bp]:
            p[bp] = ap
            size[ap] += size[bp]
            for v in rev[bp]:
                rev[ap].add(v)
                dp2[v] = (dp2[v] + foot[bp] - foot[ap]) % mod
        else:
            p[ap] = bp
            size[bp] += size[ap]
            for v in rev[ap]:
                rev[bp].add(v)
                dp2[v] = (dp2[v] + foot[ap] - foot[bp]) % mod
        #print (dp2,"end",foot)
        #part_max[ap] = part_max[bp] = max(part_max[ap] = part_max[bp])
        return False
N,M = map(int,stdin.readline().split())
lis = [ [] for i in range(N) ]
for i in range(M):
    u,v = map(int,stdin.readline().split())
    u -= 1
    v -= 1
    lis[u].append(v)
    lis[v].append(u)
p = [i for i in range(N)]
size = [1] * N
rev = [ set([i]) for i in range(N) ]
#part_max = [i for i in range(N)]
dp  = [1] * N
dp2 = [0] * N
foot = [0] * N
mod = 998244353
for v in range(N):
    p2u = {}
    
    for u in lis[v]:
        if u < v:
            p_of_u = uf_find(u,p)
            if p_of_u not in p2u:
                p2u[p_of_u] = u
            p2u[p_of_u] = min(p2u[p_of_u] , u)
    for p_of_u in p2u:
        dp[v] += dp2[p2u[p_of_u]] + foot[p_of_u]
    dp[v] %= mod
    # merge
    for u in lis[v]:
        if u < v:
            vp = uf_find(u,p)
            up = uf_find(v,p)
            if vp != up:
                uf_union(up,vp)
    allp = uf_find(v,p)
    foot[allp] += dp[v]
    foot[allp] %= mod
    #print (dp,dp2,foot,rev)
    
for i in range(N):
    ip = uf_find(i,p)
    #print (i+1,(dp2[i] + foot[ip]) % mod)
print (sum(dp) % mod)
            
            
            
        