CodeForces - 990G(点線のルールリスト数+)

トピック:https://vjudge.net/contest/307753#problem/J

質問の意味:どのように多くの木の異なる数のそれぞれをGCDツリー、各点が重みを持っている、あなたは今聞いて、

アイデア:点線ルール、全ての第一のみ1E5の範囲、そして、我々はGCDつのパスを記録し、我々は重力の中心における経路を決定する見つける、数GCDの各々は、このパスは、要素の親ノード、ナンバーワンの異なる要因でなければなりません小さな数は、実際には、さまざまな要因の数に相当しますいくつかの数字であるため、異なるパスの数は確かに非常に少しGCD、我々はパスを評価することができサブツリーを横断する際に、直接暴力の前に現れ、および複雑さがあるべきO(N * LOGNの*のLOGN)の

この問題は、特にタイトなタイムカードである私は、マップレコードの異なる数の数を使用していたし、残業が、私はそれが理由のより多くのログだと思う、私は(1)を取るが、実際にマップを考えるようにリンクリストOを変更ことがわかりました実際には、ログがノード来るの数に基づいており、私はめったに異なる番号をGCDない、実際には、近いOへこのログは、(1)、本当の理由-ハング入力します(デッドピット)

 

書式#include <cstdioを> 
する#include <CStringの> 
の#include <cmath> 
の#include <アルゴリズム> 
書式#include <iostreamの>  
の#include <ベクトル> 
の#include <キュー> 
の#include <マップ>
 に#define MAXN 200005
 の#defineのmod 0x3f3f3f3f
 使用して 名前空間STD; 
typedefの長い 長いLL。
構造体の縁{
     INT 次へ。
} E1 [ 2 * MAXN]。
構造体ノード{ 
    次LL。
    ヴァルLL; 
    BJ LL; 
}フラグ[MAXN]。
LLダ。
ベクター<LL> MP [MAXN]、XXは[MAXN]; // 保存に十分な図
LL E [MAXN]; 
LL E2 [ 20です * MAXN];
 BOOL VIS [MAXN]; // タグは、重力を利用している 
MAXSIZE北韓[MAXN ]、DIS [MAXN]、D [MAXN]、YJ [MAXN]、最終[MAXN]; // 現在のノードのMAXSIZE最大サブツリー 
LL SIZ [MAXN]、XDの[MAXN]; // 重力D距離の中心にDIS出現し 
、LLのN-、M、K、RT、SUM、QE、QE2、ANS1、ANS2、CNT、ヘッド   // 現在のノードの距離E番号サブツリーSIZ重力RTが現在表す表示 
インラインボイド読み取り(LL &X){ 
    X = 0 ; チャー C = GETCHAR();
     一方、(C> ' 9 '|| C <' 0 ')C = GETCHAR()。
    一方、(C <= ' 9 ' && C> = ' 0 ')x =(x << 3)+(X << 1)+ C- ' 0 '、C = GETCHAR()。
} 
ボイド検索(LLのX、LLのF){ // 找出重心 
    SIZ [X] = 1 
    MAXSIZE [X] = 0 ;
    以下のためにint型 I [x]は最後=; I; I = E1 [I] .next){ 
        LLのV = E1 [i]の.TO。
        もし(|| VIS [V] FのV ==)継続 ; // VIS配列タグは、重力を使用している
        (V、X)検索、
        SIZ [X] + = SIZ [V]、
        MAXSIZE [X]は = MAX(MAXSIZE [X]、SIZ [V]); 
    } 
    MAXSIZE [X] = MAX(MAXSIZE [X]、SUM-SIZ [X]); // 現在のノード番号父親アイデアツリーをルートと現在の数=サブツリーを減算することにより、ノードの合計数
    IF(MAXSIZE [X] < MAXSIZE [ RT]){ 
        RT = X; 
    } 
} 
ボイド INSERT(INT U、int型V)
{ 
    E1 [ ++ CNT] .TO = V; E1 [CNT]最終.next = [U];最終[U] = CNT。
    E1 [ ++ CNT] .TO = U; E1 [CNT] =最終.next [V];最終[V] = CNT。
} 
ボイドget_dis(LLのX、LL F、LL LEN、LLルート){ 
    
    YJ [LEN] ++ ; 
    LLトン = ヘッド。
    一方、(T =! - 1 ){ 
        YJ [__ GCD(T、LEN)] + = フラグ[T] .val。
        T = フラグ[T] .next。
    } 
    E [QE] = LEN。
    QE ++ ;
    以下のためにint型 I [x]は最後=; I; I = E1 [I] .next){ 
        LLのV = E1 [i]の.TO。
        もし(V == F || VIS [V])続けます// DIS [q.first] =(DIS [X] + LEN)%3。
        get_dis(V、X、__ GCD(LEN、XD [V])、根)。
    }     
} 
ボイド分割(LLのX){ 
    VIS [X] = 1 // のprintf( "RT =%LLD ANS1 =%LLD \ n"、X、ANS1)。
    以下のためにint型 I [x]は最後=; I; I = E1 [I] .next){ 
        LLのV = E1 [i]の.TO。
        QE = 0 ;
        もし(VIS [V])続けます// DIS [X] = q.second。
        get_dis(V、X、__ GCD(XD [X]、XD [V])、X)。
        INT J = 0 J ++; J <QE {)
             場合(ヘッド== - 1 ){ 
                ヘッド = E [J]。
                フラグ[E [J]のval = 1 
                フラグ[E [J]次。 = - 1 
                フラグ[E [J] BJ = 1 
            } 
            そう であれば(フラグ[E [J] BJ ==。0 ){ 
                フラグ[E [J]ヴァル。 = 1 
                フラグ[E [J]次 = ヘッド。
                フラグ[E [J] BJ = 1 
                ヘッド = E [J]。
            } 
            { 
                。フラグ[E [J]ヴァル ++ 
            } 
        } 
    } 
    LL T = ヘッド。
    一方、(T =! - 1 ){ 
        フラグ[T] .bj = 0 
        T = フラグ[T] .next。
    } 
    ヘッド = - 1 // QE2 = 0; 
    以下のためにint型 I =最後[X]; I; I = E1 [I] .next){ 
        LL Q = E1 [i]の.TO。
        もし(VIS [Q])続けます// (ダ> 0)ブレークであれば、
        合計=SIZ [Q]。
        RT = 0 ; 
        MAXSIZE [RT] = MOD。
        (Q、X)を求めます。
        分割(RT)。
    } 
//     VIS [X] = 0; 
}
 ボイドのinit(){ 
    ANS1 = 0 ; ANS2 = 0 
    ヘッド = - 1 // ため(INT i = 0; iが<= N + 1; I ++)MP [I] .clear(); 
    以下のためにint型 i = 0 ; iが<= N + 1、iは++)VIS [I] = 0 ;
    // ため(INT i = 0; iが<= N + 1; I ++)フラグ[I] = 0; 
    以下のためのint型私は=0 ; iが<= N + 1、iは++)YJ [I] = 0 ; 
} 
int型のmain(){ 
    LLのT; 
    (n)を読み出します。
        LL、B、C。
        その中に(); 
        XX LL; 
        以下のためにint型 i = 1 ; iが<= N; iは++ ){ 
          読み出す(XD [I])。
          YJ [XD [I]] ++ ; 
        } 
        のためにint型 I = 1 ; I <= N- 1 ; iが++ ){ 
            (A)を読み出します。
            (B)を読み取ります。
             インサート(B)
        }  = N。//当前节点数 
        RT = 0 
        [MAXSIZE 0 ] = MOD。// 置初值 
        見つける(10 ); 
        分割(RT)。
        以下のためにint型 I = 1 ; I <MAXN; iは++ ){
             場合(YJを[I] == 0続けます
            COUT << I << "  " << YJ [I] << " の\ n " // のprintf( "%I64d%I64d \ n"は、I、YJ [I])。    
        } 
}

 

おすすめ

転載: www.cnblogs.com/Lis-/p/11370670.html