LCTのBZOJ3514 Codechef MARCH14のGERALD07強化版+永続セグメントツリー

私は一人で出てくると、まだ非常に満足してカットオフしたい〜

コード: 

#include <ビット/ STDC ++。H> 
に#define N 400005   
の#define INF 1000000000 
freopenはfreopenはの#define setIO(S)(S ".IN"、 "R"、STDIN)、(S ".out"を、 "W"、 STDOUT)
名前空間stdを使用。
INT RT [N]。    
構造体のエッジ
{ 
    U、V、C int型。
    エッジ(INT U = 0、INT V = 0、INT C = 0):U(U)、V(V)、C(C){} 
} E [N]。  
構造体Union_Find_set 
{ 
    int型のP [N]。  
    INITを無効()
    { 
        [I] = iがP(++ iは; iがNを<I = 0をINT)ため、
    } 
    INT(INT X)を見つける
    { 
        ?戻りP [X] == X X:Pは[X] =(P [X])を見つけます。
    } 
    int型のマージ(int型のx、int型のY)
    { 
        X =検索(X)、Y =(y)を見つけます。
        IF(!X = Y) 
    { 
        !返す(T [T [X] .F] .CH [0] == X || T [T [X] .F] .CH [1] == X)
    }
            P [X] = Y。
            1を返します。
        } 
        { 
            0を返します。
        } 
    } 
} UFS。
構造体Link_Cut_Tree 
{ 
    の#define LSONのT [X] .CH [0] 
    の#define rson T [X] .CH [1] 
    INT STA [N]。  
    構造体ノード
    { 
        INT CH [2]、F、分、ID、ヴァル、REV。  
    } T [N]。
    INT GET(INT X)
    { 
        [1] == X [T [X] .F] .CH Tを返します。  
    } 
    INT ISRT(INT X)
    ボイド押し上げ(INT X)
    { 
        T [X] .min = T [X] .val、T [X] = xを.ID。   
        もし(Tの【のLSON] && LSON .min <T [X] .min)T [X] .min = T [LSON] .min、T [X] .ID = T [LSON] .ID。
        IF(rson && T [rson] .min <T [X] .min)T [X] .min = T [rson] .min、T [X] .ID = T [rson] .ID。   
    } 
    ボイドマーク(INT X)
    { 
        IF(x)はT [X] .rev ^ = 1、スワップ(LSON、rson)。
    } 
    ボイドプッシュダウン(int型X)
    { 
        IF(X && T [X] .rev)
        { 
            T [X] .rev = 0。
            (LSON)マーク(LSON)であれば、
            もし(rson)マーク(rson)。   
        } 
    } 
    ボイド回転(int型X)
    { 
        INT古い= tの[X] .F、=さt(x)を取得= [古い] .Fを折ります。
        (!ISRT(旧))であればT [倍] .CH = xの[T [1] ==古い[] .CH倍]。
        T [古い] .CH [た] = tの[X] .CH [れる^ 1]、T [T [古い] .CH [れる] F =古いです。  
        T [X] .CH古い= [れる^ 1]、T = xと.F [古い]、T [X] .F =折ります。
        腕立て伏せ(旧)、腕立て伏せ(x)は、
    } 
    ボイドスプレイ(INT X)
    { 
        int型のV = 0、U = Xを、FA。
        STAは[++ V] T [U] .Fを=(!; ISRT(u)はuが= T [U] .F STA [++ V = U)のために  
        用(; V; - v)の押下(STA [V])。   
        (U = T [U] .F(FA = tの[X] .F)= Uが;!(X)を回転させる)ための
            場合(T [FA] .F = uは!)
                (==)(FAを取得回転?(x)のFAを取得します。x);  
    } 
    ボイドアクセス(int型X)
    { 
        (; X; Y = X、X = T [X] .F INT Y = 0)のための
            スプレイ(X)、rson = Y、押し上げ(X)。 
    {
    }
    無効makeroot(int型x)の
    INTの更新(int型のx、int型のL、R INT、INT P、INT D)
        アクセス(X)、スプレイ(X)、マーク(X)。
    } 
    ボイドスプリット(int型のx、int型のY)
    { 
        makeroot(X)、アクセス(Y)、スプレイ(Y)。
    } 
    ボイドリンク(int型のx、int型のY)
    { 
        makeroot(x)は、T [X] .F = Y。
    } 
    ボイドカット(int型のx、int型のY)
    { 
        makeroot(X)、アクセス(Y)、スプレイ(Y)。   
        T [Y] .CH [0] = tの[X] .F = 0。
        突き上げ(Y)。
    } 
    の#undef LSON用
    の#undef rson 
} LCT。
構造体Segment_Tree 
{ 
    int型のTOT。  
    INTのLSON [N * 20]、rson [Nの* 20]、合計[N * 20]。  
    { 
        INT OO = ++ TOT。     
        LSON [OO] = LSON [X]、rson [OO] =のrson [X]、和[OO] =和[X] + D。  
        IF(L == R)戻りOO。
        INT半ば=(L + R)>> 1。   
        IF(p <= MID)LSONの【のOO] =アップデート(LSON [x]は、L、中、P、D)。
        他rson [OO] =アップデート(rson [x]は、中間+ 1、R、P、D)。
        OOを返します。
    } 
    INTクエリ(int型のx、int型のL、int型のR、int型のL、R INT)
    { 
        (!X)であれば0を返します。
        IF(L> = L && R <= R)戻り和[X]。
        半ば=(L + R)>> 1、INT、再= 0。   
        IF(L <= MID)再+ =クエリ(LSON [x]は、L、中、L、R)。
        IF(R> MID)再+ =クエリ(rson [x]は、中間+ 1、R、L、R)。
        再を返します。
    } 
} TR。
int型のmain()
{ 
    // setIO(」 
    int型N、M、I、J、K、TY。
    scanf関数( "%D%D%D%D"、&N、&M、&K、&TY)。
    lct.t [0] .val = INF。      
    lct.t [I] .val = INF、lct.pushup(I)、(I ++; iが<= N I = 1)のために 
    ufs.init();  
    (; I <= M + I I = 1)のための
    { 
        scanf関数( "%D%D"、&E [I] .U、&E [I] .V)。     
        int型のu = E [i]の.U。
        int型のV = E [i]の.V。
        int型_new =私はN +; 
        RT [I] =のRT [I-1];  
        (U == V)であれば
        { 
            続けます。
        }   
        RT [I] = tr.update(RT [I-1]、1、M、I、1)。        
        IF(ufs.merge(U、V))
        {   
            lct.t [_new] .val = I。
            lct.pushup(_new)。    
            lct.link(U、_new)。
            lct.link(_new、V);   
        } 
        { 
            lct.split(U、V)。   
            INT CC = lct.t [V] .ID。    
            lct.cut(CC、E [CC-N] .U)。  
            lct.cut(CC、E [CC-N] .V)。      
            RT [I] = tr.update(RT [I]、1、M、CC-N、-1);  
            lct.t [_new] .val = I。  
            lct.pushup(_new)。      
            lct.link(_new、U)。  
            lct.link(_new、V);   
        } 
    } 
    int型lastans = 0。
    用(i = 1; iは= K <; ++ I)
    { 
        int型のL、R。
        scanf関数( "%dの%のD"、&L&R)。
        (TY)の場合
        { 
            L ^ = lastans。 
            R ^ = lastans。
            IF(L> R)スワップ(L、R)。
        } 
        lastans = N-tr.query(RT [R]、1、M、L、R)。   
        printf( "%d個の\ n"、lastans)。  
    } 
    0を返します。
}

  

おすすめ

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