彗星OJ - コンテスト#6 D.別のチャネルツリーのタイトル互いに素-設定したカウント+ +思考

コード: 

#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を返します。
}

  

おすすめ

転載: www.cnblogs.com/guangheli/p/11242060.html