HDU - 5398 GCDツリーLCT

5398 - HDU

前処理は、その上に、それLCTのメンテナンスのすべての瞬間にまたがる最大を維持します。

#pragma GCC最適化(2)
 の#pragma GCCの最適化(3)
 の#pragma GCCの最適化(4)
の#include <ビット/ STDC ++。H>
 に#define LL長い長
 の#define LD長い二重
 の#defineは、符号なしの長い長いULL
 の#define第Fiが
 #define SE第二
 の#define MK make_pair
 の#define PLL対<LL、LL>
 の#define PLI対<LL、整数>
 の#define PII対<整数、整数>
 の#define SZ(X)((INT)x.size() )
 の#define ALL(X)(X).begin()、(X).END()
 の#define FIOイオス:: sync_with_stdio(偽); cin.tie(0)。使用して

 名前空間はstd; 

CONSTの INT N = 3E5 + 7 const  int型 INF = 0x3f3f3f3f constの LL INF = 0x3f3f3f3f3f3f3f3f const  int型のmod = 998244353 ;
constの ダブル EPS = 1E- 8 ;
CONST  ダブル PI = ACOS( - 1 )。

テンプレート < クラス T、クラス S>インラインボイド追加(T&、S b)は{A + B =。もし(> = MOD)A - = MOD;} 
テンプレート <クラス T、クラス S>インラインボイドサブ(T&、S b)は、{ - = B。もし(< 0)、A + = MOD;} 
テンプレート < クラス T、クラス S>インラインBOOL chkmax(T&、S B)は{ 返す <bは?= B、;} 
テンプレート < クラス T、クラス S>インラインブール chkmin(T&、S b)は{ 返す > bは?= B、;} 

MT19937 RNG(。。クロノ:: steady_clock ::今()time_since_epoch())(カウント)。

int型のn; 
[N] ANS LL。
今LL; 
int型のTOT;
INT U [N]、V [N]。
ベクター < INT > FAC [N]。

構造体LCT {
 の#define L(X)(CH [X] [0])
 の#define R(X)(CH [X] [1])
     INT FA [N]、CH [N] [ 2 ]、REV [N ]、SZ [N]、Q [N]。
    PII MN [N]、W [N]。
    無効のinit(int型n)を{
         ためint型 i = 0 ; iが<= N; iは++ ){ 
            FA [I] = REV [I] = 0 ; 
            SZ [I] = 1; 
            MN [i]は W = [I] = MK(1000000 、I)。
            CH [i]が[ 0 ] = CHを[I] [ 1 ] = 0 ; 
        } 
        TOT = N + 1 
    } 
    インラインブール isroot(INT X){
         リターン L(FA [X])= X && R(FA [X])=!X。
    } 
    インラインボイドプル(INT X){ 
        SZ [X] = SZ [L(X)] + SZ [R(X)] + 1 
        MN [X] = [X] W。
        chkmin(MN [x]は、MN [L(X)])。
        chkmin(MN [x]は、MN [R(X)])。
    } 
    インラインボイドプッシュ(int型X){
         場合(REV [X]){ 
            REV [X] = 0 ; スワップ(L(x)は、R(X)); 
            REV [L(X)] ^ = 1 ; REV [R(X)] ^ = 1 ; 
        } 
    } 
    インラインボイド腐敗(INT X){
         int型、Y = FA [X]、Z = FA [Y]、L、R。
        もし(CH [Y] [ 0 ] == x)はL = 0、R = L ^ 1 リットル= 1R = L ^ 1 もし(!isroot(Y)){
             場合(L(Z)== y)がL(Z)=のX。
            そうでなければ R(Z)=のX。
        } 
        FA [X] = Z; FA [Y] = xと; FA [CH [X] [R] = Y。
        CH [Y] [L] = CH [X] [R]。CH [X] [R]は= yと、
        (Y)引っ張ります。(x)を引きます。
    } 
    インラインボイドスプレイ(INT X){
         int型のトップ= 1Q [トップ] =のX。
        以下のためのint型のq [++トップ] =!;; isroot(I)は、i = FA [i]はI = x)のFA [i]は、
        以下のためのint型 I;; i-- I =トップ)プッシュ(Q [I])。
        一方、(!isroot(X)){
             int型、Y = FA [X]、Z = FA [Y]。
            もし(!isroot(Y)){
                 もし、((L(Y)== X)^(L(Z)== Y))腐敗(X)。
                他の腐敗(Y); 
            } 
            腐敗(X)。
        } 
    } 
    インラインボイドアクセス(INT X){
         ためint型、Y = 0 ; X; Y = X、X = FA [X]){ 
            スプレイ(X)。
            R(X) =
        } Y。
            (x)を引きます。
    } 
    インライン Y){ボイド makeroot(INT X){ 
        アクセス(X)。スプレイ(X)。REV [X] ^ = 1 ; 
    } 
    インラインINT FindRootで(INT X){ 
        アクセス(X)。スプレイ(X)。
        一方、(L(X))×=のL(X)
        リターンのx; 
    } 
    インラインボイドスプリット(int型のx、int型のY){ 
        makeroot(X)。アクセス(Y)。スプレイ(Y)。
    } 
    インラインボイドリンク(int型のx、int型
        makeroot(x)は、FA [X]= Y。スプレイ(X)。
    } 
    インラインボイドカット(int型のx、int型のY){ 
        スプリット(X、Y)
        もし(L(Y)== X)L(Y)= 0、FAは[X] = 0 
    } 
    ボイド変化(int型のx、int型の Y、int型の重量){
         場合(FindRootで(X)=!FindRootで(Y)){
             ++ TOT。
            W [TOT] = MK(重量、TOT)。
            U [TOT] = xと; V [TOT = Y。
            SZ [TOT]= 1つの
            リンク(X、TOT)。
            リンク(Y、TOT)。 + = 重量;
            返します
        } 

        makeroot(X)。
        アクセス(Y)。
        スプレイ(Y)。
        PII MINVAL = MN [Y]。

        もし(minVal.fi> =重量)のリターン; 
        カット(minVal.se、V [minVal.se])。
        カット(minVal.se、U [minVal.se])。 - = minVal.fi。

        W [minVal.se] = MK(重量、minVal.se)。
        U [minVal.se] = xと; V [minVal.se] = Y。
        SZ [minVal.se] = 1; 
        リンク(X、minVal.se)。
        リンク(Y、minVal.se)。 + = 重量; 
    } 
} LCT。

INT メイン(){
     ためint型 i = 1 ; iが<= 100000 ; I ++ ){
         ためint型 J = iは+ I; J <= 100000 ; J + = I){ 
            FAC [J] .push_back(I)。
        } 
    } 

    lct.init(100000 )。

    以下のためにint型 I = 2 ; iは= < 100000 ; I ++){
        INTのJ:FAC [i])と{ 
            lct.change(I、J、J)。
        } 
        ANS [I] = 今。
    } 

    一方(scanf関数(" %のD "、&​​N)=!EOF){ 
        のprintf(" %LLDする\ n " 、ANS [N])。
    } 
    戻り 0 
}

 

おすすめ

転載: www.cnblogs.com/CJLHY/p/11274169.html