質問表面:https://www.luogu.com.cn/problem/P4556
(x、y)のZプラス1でパスに。
ツリーには違いがあることができます。
xおよびyがインクリメントされます。LCAはマイナス1、マイナス1つのLCAは父です。
しかし、多くの異なる種があるためです。
各点は、ツリーラインを維持するために必要。
合併のどの種類の最大を求めているとき。
最後に、統計的な答えは、DFS。
シンプルなアイデアは、メインコードは長いです。
コードは以下の通りであります:
#pragma -gcc-最適化( "O2、Ofast、インライン、アンロール-全てループ、-ffast-数学") の#pragma -gcc-目標( "AVX、SSE2、SSE3、SSE4、POPCNT") の#include <ビット/ 。STDC ++ H> 使用して 名前空間STDを、 CONST INT MAXN = 100010 ; int型TT、N、M、 構造体ノード{ int型NXT、へ; の#define NXT(X)E [X] .nxt の#define(X)E [xに] .TO } E [MAXN << 1 ]; int型のヘッド[MAXN]、TOT、DEP [MAXN]、[MAXN] [F 21 ]、RT [MAXN]、NUM、CNT、X [MAXN]、Y [MAXN ]、Z [MAXN]、valが[MAXN]は、[MAXN] ANS; インラインボイド(追加のint X、int型のY){ (に TOT ++)= yと; NXT(TOT) =ヘッド[X];頭部[X] = TOTを、 } キュー < INT > Q。 インライン長い{read()は 長い X = 0、F = 1。チャー C = GETCHAR()。 一方、(C> ' 9 ' || C < ' 0 '){ もし、(C == ' - ')、F * = - 1 ; C = GETCHAR();} 一方、(C> =' 0 ' && C <= ' 9 ')、X = X * 10 + C- ' 0 '、C = GETCHAR()。 リターンのx *のF; } インラインボイドBFS(){ q.push(1); DEPは、[ 1 ] = 1 。 一方、(q.size()){ int型のx = q.front(); q.pop()。 以下のために(int型 I =ヘッド[X]; I; I = NXT(I)){ int型 =への(I) もし(DEP [に対して])続行。 【に】DEP = DEP [X] + 1 。 F [に対する] 0 ] =のX。 用(INTの J = 1 J ++; J <= TT ) F [へ] [J] = F [F [へ] [J- 1 ]] [J- 1 ]。 (へ)q.push。 } } } インラインINT LCA(int型のx、int型Y){ 場合(DEP [X]> DEP [Y])スワップ(X、Y) 以下のために(int型私はTTを=; I> = 0 ; i-- ) の場合(DEP [F [Y] [I]]> = DEP [X])Y = F [Y] [I]。 もし(x == y)は戻りX。 以下のために(int型 = TTをIを、I> = 0 ; i-- ) であれば(!F [x]は[I] = F [Y] [i])と、X = F [X] [i]は、Y = Y [F ][私]; 戻り [X] [F 0 ]。 } 構造体ツリー{ int型LC、RC、DT、TG。 } T [MAXN * 80 ]。 ボイド挿入(int型 P、int型の L、INT R、INT VL、INT D){ 場合(1- == {R) T [P] .DT+ = D。 T [P] .tg = T [P] .DT?L:0 。 返します。 } INT半ば=(L + R)>> 1 。 もし(VL <= MID){ 場合(!T [P]を得た。LC)T [P]を得た。LC = ++ NUM。 (T [P]を得た。LC、L、中間、VL、D)を挿入します。 } 他{ 場合(!T [P] .RC)T [P] .RC = ++ NUM。 インサート(T [P] .RC、中間 + 1 、R、VL、D)。 } T [P] .DT = MAX(T [T [P]を得た。LC] .DT、T [T [P] .RC] .DT)。 T [P] .tg = T [T [P]を得た。LC] .DT> = T [T [P] .RC] .DT?T [T [P]を得た。LC] .tg:T [T [P] .RC] .tg。 } INTマージ(INT P、整数 qは、整数 L、INT R){ 場合(!P)リターンQ。 もし(!Q)リターンのp; もし(L == R){ T [P] .DT + = T [Q] .DT。 T [P] .tg = T [P] .DT?L:0 。 リターンのp; } INT半ば=(L + R)>> 1 。 T [P]を得た。LC = マージ(T [P]を得た。LC、T [Q]を得た。LC、L、MID)。 T [P] .RC =マージ(T [P] .RC、T [Q] .RC、ミッド+1 、R)。 T [P] .DT = MAX(T [T [P]を得た。LC] .DT、T [T [P] .RC] .DT)。 T [P] .tg = T [T [P]を得た。LC] .DT> = T [T [P] .RC] .DT?T [T [P]を得た。LC] .tg:T [T [P] .RC] .tg。 リターンのp; } ボイド DFS(int型X){ ため(int型 I =ヘッド[X]; I; I = NXT(I)){ int型 =の(I)に、 もし([に対する] DEP <= [X] DEP)続けます。 DFS(へ)。 室温[X] =([X]、RT、[TO] RTマージ1 CNT)。 } ANS [X] = T [RT [X]のTgを。 } INT )(主 { N = read()は、M = read()は、 TT =(INT)(ログ(N)/ログ(2))+ 1 。 以下のために(int型私= 1 ; iがN <; Iは++ ){ int型 X、Y; X =読み取る(); Yは。= 読み取ります(); (x、y)を追加し、(x、y)を加えます。 } BFS()。 以下のために(int型 i = 1 ; iが<= N; iは++)RTを[I] = ++ NUM。 以下のために(int型 I = 1 ; I <= M; iは++ ){ X [i]が読み取り=(); Y [i]を読み出す=(); Z [I] = 読み取ります(); ヴァル[I] = Z [i]は、 } ソート(ヴァル + 1、ヴァル+ 1 + M)。 CNT =ユニーク(ヴァル+ 1、ヴァル+ 1 + M)-val- 1 。 以下のために(int型 I = 1 ; I <= M; iは++ ){ int型、X = X [i]は、Y = Y [i]は、 INT Z = LOWER_BOUND(ヴァル+ 1、ヴァル+ 1 + CNT、Z [i])と- ヴァル。 INT LC = LCA(X、Y) インサート(RT [X]、1、CNT、Z、1 )。 (RT [Y]、インサート1、CNT、Z、1); (RT [LC]、インサート1、CNT、Z、 - 1 )。 もし([LC]は[F 0 ])を挿入する(RT [F [LC] [ 0 ]、1、CNT、Z、 - 1 )。 } DFS(1 )。 以下のために(int型私= 1 iが++; iが<= N)のprintf(" %d個の\ n " 、ヴァル[ANS [I])を、 リターン 0 ; }