コード:
#include <cstdioを> する#include <アルゴリズム> の#include <CStringの> する#include <ベクトル> の#define setIO(S)freopenは(S ".IN"、 "R"、STDIN) の#define MAXN 200004 の#define MOD 998244353 の#define LL長い長い 名前空間stdを使用。 インライン(LLのB、LL)を追加しちゃう{ リターン(A + B)%MOD。 } {(LLのB LL)インラインLLド ((%のMOD) - (B%MOD)+ MOD)リターン%MOD。 } int型N、エッジ; INT HD [MAXN]、[MAXN]に、NEX [MAXN]、DEP [MAXN]、[MAXN] F [MAXN] SIZ、息子[MAXN]、トップ[MAXN]、P [MAXN]、SZ [MAXN] ; LL INV [MAXN]、MUL、G [MAXN]、ANS。 構造体ノード{ UをINT、V。 ノード(INT U = 0、V INT = 0):U(U)、V(V){} }。 ベクター<ノード> VI [MAXN]。 ベクター<INT> G [MAXN]。 LLのqpow(LLベース、LLのK){ LL再= 1。 一方、(K){ (K&1)が再場合= *基地%のMOD再。 基地=ベース*基地%のMOD。 K >> = 1。 } 戻り再。 } ボイド追加(INT U、V INT){ NEX [++エッジ] = HD [U]、HD [U] =縁、[エッジ]へ= V。 } ボイドDFS1(UをINT){ DEP [U] = DEP [F [U] + 1、SIZ [U] = 1、G [DEP [U]一back(U)。 以下のために(INT I = HD [U]; I; I = NEX [I]){ int型V =乃至[I]。 (V ==のF [U])続行。 DFS1(V)、SIZ [U] + = SIZ [V]。 IF(SIZ [V]> SIZ [息子[U])息子[U] = V。 } } int型のFXは=(X)、FY =見つける(y)を見つけます。 ボイドDFS2(INT U、INT TP){ トップ[U]はTPを=。 IF(息子[U])DFS2(息子[U]、TP)。 以下のために(INT I = HD [U]; I; I = NEX [I]){ int型V =乃至[I]。 IF(Vの== F [U] || V ==息子[U])続けます。 DFS2(V、V); } } int型LCA(int型のx、int型Y){ (TOP [X] ^トップ[Y]){ながら [X]トップ]?X = F [x]は上部]> DEP [Y]トップ[] DEP Y = F [TOP [Y]。 } 戻りDEP [X] <DEP [Y]は、x:yの。 } ボイドのinit(){ (I = 0 int型、iがMAXNを<; ++ i)に対するP [I] = iは、SZ [I] = 1。 } INT(INT X){見つける ?戻りP [X] == X X:Pは[X] =(P [X])を見つけます。 } ボイドマージ(int型のx、int型のY){ IF(FX!= FY){ MUL = MUL * INV [SZ [FX] +1]%MOD * INV [SZ [FY] +1]%MOD。 P [FX] = FY、SZ [FY] + = SZ [FX]。 MUL = MUL *(SZ [FY] +1)%MOD。 } } ボイド初期化(){ INIT()[1] = 1、MUL = qpow(2、n)のINV。 以下のために(INT I = 2、I <MAXN; ++ I)INVの[I] =(LL)(MOD-MOD / I)* INV [MOD%I]%MOD。 } int型のmain(){ // setIO( "入力")。 scanf関数( "%のD"、&N); 以下のために(; iは= N <; I = int型2 ++ I)のscanf( "%d個"、&F [i])と、追加(F [i]は、I)。 初期化()、DFS1(1)、DFS2(1,1)。 VI [DEP [I] -1] .push_back([i])とノードF(I)(; iが<= N I ++ iは2 = INT)のために、 {(; iが<= N I ++ iは1 = INT)のために INT J = 1(のためにあり、j < VI [DEP [G [I] [J]] - DEP [LCA(G [I] [J]、G [i]は[J-1])]]一back(ノード(G [I] [J]。 G [I] [J-1]))。 } } ANS =ド(MUL、N + 1)。 {(; iが<= N I ++ I = 1 INT)のため のために(INT J = 0;)J <VI [I] .size(; ++ j)を マージ(VI [I] [J] .U 、VI [I] [J] .V)。 ANS =追加(ANS、デ(MUL、N + 1))。 } のprintf( "%LLDする\ n"、ANS)。 0を返します。 }