질문은 표면 : 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>. 하여 스페이스 성병; 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, 발은 [maxn]는 [maxn] ans와; 인라인 무효(ADD INT (X), INT의 Y) { (에 ++ 등록 무비) = Y를; NXT (TOT) = 헤드 [X] 헤드 [X]는 = TOT 단계; } 큐 < INT > Q 단계; 인라인 긴 () {판독 긴 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 ) 증착은 [ 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]> 출발 [Y]) 스왑 (X, Y); 위한 ( int로 난을 TT =; I> = 0 ; 난 ... ) 만약DEP ([F [Y] [I]]> = DEP [X]) Y = F [Y] [I]; 경우 (X == y)를 반환 X; 위한 ( int로 = TT를 I 단계; I> = 0 ; 난 ... ) 의 경우 (! F [X] [I] = F [Y] [I]), X = F [X] [I], Y = Y [F ][나는]; 반환 f를 [X] [ 0 ] } 구조체 나무 { INT의 LC, RC, DT, TG; t} [maxn * 80 ]; 보이드 인서트 ( INT의 P, INT의 L, INT의 R, INT의 VL, INT의 d) { 경우 (L의 == 된 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 = 최대 (t [t [P] .lc] .dt, t [t [P] .RC] .dt); t [P] .tg = t [t의 [피] .lc]> = t .dt [t [P] .RC] .dt?t [t [P] .lc] .tg : t [t의 [피] .RC] .tg; } INT의 병합 ( INT의 P, INT의 Q, INT의 L, INT의 R) { 경우 (! 피) 리턴 큐; 만약 (! Q) 반환 피; 경우 (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 = 최대 (t [t [P] .lc] .dt, t [t [P] .RC] .dt); t [P] .tg = t [t의 [피] .lc]> = t .dt [t [P] .RC] .dt? t [t [P] .lc] .tg : t [t의 [피] .RC] .tg; 반환 P는; } 공극 DFS ( INT의 X) { 위해 ( int로 I = 헤드 [X] I, I = NXT (I)) { INT = 행 (I)에; 경우 ([을] DEP <= [X] DEP) 계속 ; DFS (행); RT는 [X] = 병합 (RT [X], RT [행] 1 CNT); } ANS [X] =를 t [RT의 [X] TG.; } INT ) (메인 { N = () m 읽기 ) (판독; TT = ( INT ) (로그 (N) / 로그 ( 2 )) + 1 ; 위한 ( int로 I = 1 ; i가 N이 <I ++ ) { INT X, Y는, X = 읽기 (); Y가 = 판독 (); (x, y)를 추가, 부가 (Y, X); } BFS (); 위한 ( int로 I = 1 ; i가 <= N; 내가 ++)을 RT [I] = ++ NUM; 위한 ( int로 I = 1 ; I <= m; 내가 ++ ) { X는 [i]를 판독 = (), Y [I]를 판독 = (), Z [I] = 판독 (); 발 [I] =Z [I]; } 정렬 (브로 + 1 , 발은 + 1 + m); CNT는 고유 = (브로 + 1 , 발 + 1 + m) -val- 1 ; 위한 ( int로 I = 1 ; I <= m; 내가 ++ ) { 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로 I = 1 ; 나는 <= N; ++ i가 ()에서 printf " % D \ 없음 " , 발 [ANS [I])를; 반환 0 ; }