羅区P4374

ボードの問題があります。

右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)
        修正(11 、nは、ID [トップ[X]、ID [x]は、Z)。
        X = FA [TOP [X]]。
    } 
    もし(x == y)のリターン;
    もし(DEP [X]> DEP [Y])スワップ(X、Y)
    修正(11、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(10 ); 
    DFS2(11 )。
    // ビルド(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 =クエリ(11 、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 ; 
}

 

おすすめ

転載: www.cnblogs.com/syzf2222/p/12386730.html