BZOJ 3319:黒と白の木の互いに素セット+オフライン+思考

コード: 

#include <cstdioを> 
する#include <アルゴリズム> 
の#include <CStringの> 
する#include <地図> 
の#include <ベクトル> 
の#include <スタック> 
の#include <キュー> 
の#define setIO(S)freopenは(S ".IN"、」 R "STDIN)、freopenは(S" .out」を、 "W"、STDOUT)   
の#define MAXN 1002002 
使用して名前空間std。  
するchar * P1、P2 *、BUF [100000]。
#define NC()(P1、P2 == &&(P2 =(P1 = BUF)+関数fread(BUF、1,100000、STDIN)、P1 == P2)EOF:* P1 ++)
int型RD(){int型のx = 0 ; チャーC = NC()。一方、(C <48)C = NC()。一方、(C> 47)x =(((X << 2)+ X)<< 1)+(C ^ 48)、C = NC()。Xを返す;} 
ベクトル<整数> G [MAXN]。
スタック<整数> S;                  
N INT、M、エッジ。
int型のTM [MAXN]、HD [MAXN << 1]、     
int型のSIZ [MAXN]、トップ[MAXN]、[MAXN] FA、
INT IDX [MAXN << 1]、ID [MAXN << 1]。     
インラインボイドaddedge(INT U、INT V、INT C){ 
    NEX [++エッジ] = HD [U]、HD [U] =エッジは、[エッジ]にVを= ID [エッジ]はCを=。   
} 
ボイドDFS1(INT U、INT FF){ 
    DEP [U] = DEP [FF] + 1、SIZ [U] = 1、FA [U] = FFを、
    以下のために(INT I = HD [U]; I; I = NEX [I]){ 
        int型V =乃至[I]。     
        (vは== FF)続けるならば、
        IDX [V] = ID [i]は、DFS1(V、U)、SIZ [U] + = SIZ [V]。
        IF(SIZ [V]> SIZ [息子[U])息子[U] = V。  
    } 
} 
ボイドDFS2(INT U、INT TP){ 
    トップ[U]はTPを=。
    IF(息子[U])DFS2(息子[U]、TP)。
    以下のために(INT I = HD [U]; I; I = NEX [I]){ 
        int型V =乃至[I]。
        もし(V == FA [U] || V ==息子[U])続けます。
        DFS2(V、V); 
    } 
} 
インラインINT LCA(int型のx、int型のY){
    一方、(DEP [U]> DEP [LCA]){
    一方(上部[X] ^トップ[Y]){ 
        DEP [トップ[X]]> DEP [トップ[Y] X = FA [TOP [X]:Y = FA [トップ[Y]。
    } 
    戻りDEP [X] <DEP [Y]は、x:yの。
} 
構造体オプト{ 
    int型OPT、X、Y。
} OP [MAXN]。
構造体ユニオン{ 
    INT P [MAXN]。
    インラインボイドのinit(){ 
        ため(INT i = 0; I <MAXN; ++ I)のP [I] = I。
    } 
    INT(INT X){見つける
        ?戻りP [X] == X X:Pは[X] =(P [X])を見つけます。
    } 
}ブラック、ホワイト。         
インラインボイドマーク(INT U、INT LCA、INT CUR){ 
    U = TM [U] black.find(U):U。   
            black.p [U] = FA [U]。   
            U = FA [U]。   
        TM [U] = CUR。      
        (!TM [FA [U]]){もし
        }     
        他{ 
            int型、Y = black.find(FA [U])。          
            black.p [U] = Y。          
            UはYを=。                  
        } 
    } 
} 
インラインボイド更新(INT U、V INT、INTのCUR){ 
    int型LCA = LCA(U、V)。
    マーク(U、LCA、CUR)、マーク(V、LCA、CUR)。     
} 
インラインボイド変化(INT U){ 
    white.p [U] = white.find(FA [U])。                
} 
int型のmain(){ 
    // setIO( "入力")。
    scanf関数( "%d個の%のD"、&N、&M)。
    {(; iがN <++ iが1 = INT)のための
        V、U int型。
        U = RD()、V = RD()。
        addedge(U、V、I)、addedge(V、U、I)。         
    }
    DFS1(1,0)、DFS2(1,1)、black.init()。                      
    (I 1 = int型; I <= M; ++ i)について{ 
        OP [I] .OPT = RD()。
        IF(OP [I] .OPT == 1)OP [I] .X = RD()。
        IF(OP [I] .OPT == 2)OP [I] .X = RD()、OP [I] .Y = RD()、更新(OP [I] .X、OP [I] .Y、私);  
    }    
    white.init()。
    (I = 2をint型++ I; iが<= n)のためのG [TM [I] == 0 M + 1:TM [I]]。一back(I)。  
    M + =(G [M + 1] .size()> 1)。
    { - (I; I> = 1、I = mは整数)のための       
        {(G [i]が.size())場合
            、INT J = 0(のために、J <G [I] .size(); ++ J )変化(G [I] [J])。        
        }そうであれば(OP [I] .OPT == 1){ 
            S.push(white.find(OP [I] .X))。                 
        }
    }               
    ながら(!S.empty()){
        のprintf( "%d個の\ n"、IDX [S.top()])。S.pop(); 
    } 
    0を返します。
}

  

おすすめ

転載: www.cnblogs.com/guangheli/p/11235798.html