ボードの問題があります。
右LCAを削除する右サイドターン点、直接ID [X]を追加するように変更されることに留意されたいです。
なお、このとき、X == Y、直接戻ります。
コードは以下の通りであります:
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 #define INF 2147483647 のconst int型 MAXN = 1E6; 整数N、M。 インラインint型リード(){ int型のx = 0、F = 1 。 チャー C = GETCHAR()。 一方、(C < ' 0 ' || C> ' 9 ' ){ もし、(C == ' - ')、F = - 1 。 C = GETCHAR()。 } しばらく(C> = ' 0 ' && C <= ' 9 ' ){ X =(X << 1)+(X << 3)+ C- ' 0 ' 。 C = GETCHAR()。 } 戻り X * F。 } INT BEG [MAXN]、NEX [MAXN]乃至[MAXN]、E。 インラインボイド追加(int型のx、int型のY){ E ++; NEX [E] = BEG [X]。 BEG [X] = E [E] =にY; } int型XX [MAXN]、YY [MAXN]。 int型【MAXN]息子[MAXN]、サイズ[MAXN]、DEP、FA [MAXN]。 インラインボイド DFS1(int型のx、int型ANC){ DEP [X] = DEP [ANC] + 1 。 FA [X] = ANC。 サイズ[X] = 1 。 用(INT I = BEG [X]; I;私は= NEX [I]){ int型 T = [I]にします。 もし(T == ANC)は継続。 DFS1(T、X)。 サイズ[X] + = サイズ[T]。 もし(サイズ[T]> サイズ[息子[X]]) 息子[X] = T。 } } int型のID [MAXN]、トップ[MAXN]、CNT。 インラインボイド DFS2(int型のx、int型TOPC){ ID [X] = ++ CNT。 トップ[X] = TOPC。 もし(!息子[X])のリターン; DFS2(息子[X]、TOPC)。 用(INT I = BEG [X]; I;私は= NEX [I]){ int型 T = [I]にします。 もし(T == FA [X] || T == 息子[X]) 続けます。 DFS2(T、T)。 } } int型TR [MAXN]、怠惰[MAXN]。 列をなしてボイド押し上げ(int型 H、INT Z){ TR [H] = 分(TR [H]、Z); 怠惰[H] = 分(怠惰[H]、Z); } インラインボイドプッシュダウン(INT H){ 場合(怠惰[H] == INF)のリターン; 突き上げ(H << 1 、怠惰[H])。 突き上げ(H << 1 | 1 、怠惰な[H])。 怠惰[H] = INF。 } インラインボイド変更(int型 H、INT L、INT R、int型のx、INT Y、INT Z){ 場合(L> Y || R <x)をリターン。 場合(L> = X && R <= Y){ 押し上げ(H、Z)。 リターン; } プッシュダウン(H)。 INTの半ば=(L + R)>> 1 。 変更(H << 1 、L、中、X、Y、Z)。 変更(H << 1 | 1、中間+ 1 、R、X、Y、Z)。 // T R [H] =分(TR [H << 1]、TR [H << 1 | 1])。 } インラインボイド MC(int型のx、int型 Y、INT Z){ 一方(上部[X] =!トップ[Y]){ 場合(DEP [TOP [X] < DEP [トップ[Y])スワップ(X、Y) 修正(1、1 、nは、ID [トップ[X]、ID [x]は、Z)。 X = FA [TOP [X]]。 } もし(x == y)のリターン; もし(DEP [X]> DEP [Y])スワップ(X、Y) 修正(1、1、nは、ID [X] + 1 、ID [Y]、Z); } / * インラインボイドビルド(int型H、INT L、int型R){ TR [H] =怠惰[H] = INF。 (L == R)戻った場合。 INTミッド=(L + R)>> 1。 ビルド(H << 1、L、MID)。 ビルド(H << 1 | 1、ミッド+ 1、R); } * / インラインINTクエリ(INT H、INT L、INT R、INT X){ 場合(L == R)戻りTR [H]。 INTの半ば=(L + R)>> 1 。 プッシュダウン(H)。 もし(MID> = X)リターンクエリ(H << 1 、L、中、X)。 他の リターンクエリ(H << 1 | 1、ミッド+ 1 、R、X); } int型のmain(){ // freopenは( "p.in"、 "R"、標準入力)。 N = read()は、M = read()は、 以下のための(int型 I = 0 ; I <= 10 * N; I ++ ) TR [I] =怠惰[I] = INF。 以下のために(INT iが= 1 ; I <N; I ++ ){ XX [I] = (読み取り) YY [I] = (読み取り) (XX [I]、YY [I])を加えます。 (YY [I]、XX [I])を加えます。 } DFS1(1、0 ); DFS2(1、1 )。 // ビルド(1,1、N)。 INT X、Y、Z。 以下のために(INT iが= 1 ; I <= M、I ++){ X=リード()、Y =読み取り()、Z = 読み取ります(); MC(X、Y、Z) } int型の AC = 0、WA = 0 。 用(INTは iは= 1 ; I <N; I ++ ){ 場合(DEP [XX [I] < DEP [YY [I])スワップ(XX [I]、YY [I])。 INT TMP =クエリ(1、1 、nは、ID [XX [I])。 TMP =(TMP == INF) - ?1 :TMP; printf(" %dの\ n " 、TMP)。 / * X =リード()。 (x == TMP)AC ++場合。 他のWA ++、printfの( "%D%D \ n"は、X、TMP); // printfの( "%d個\ n"は、TMP == INF -1:?TMP); * / } // のprintf( "%D%D \ n"は、AC、WA)。 リターン 0 ; }