トピック: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。// 置初值 見つける(1、0 ); 分割(RT)。 以下のために(int型 I = 1 ; I <MAXN; iは++ ){ 場合(YJを[I] == 0)続けます。 COUT << I << " " << YJ [I] << " の\ n " 。 // のprintf( "%I64d%I64d \ n"は、I、YJ [I])。 } }