BZOJ 4399:魔法少女LJJセグメントツリーログの統合+

コード: 

書式#include <cstdioを> 
する#include <アルゴリズム> 
書式#include <cmath> 
名前空間stdを使用。
#define LS LSON [X] 
の#defineのRS rson [X]   
の#define setIO(S)freopenは(S ".IN"、 "R"、STDIN)、freopenは(S ".out"を、 "W"、STDOUT)
CONST int型MAXN = 500000;  
const int型N = 1000000000;  
名前空間IO {   
    チャー*の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を返します。
    } 
}。   
    {INITを無効()
        [I] = iがP(++ iは; iがMAXNを<I = 0をINT)ため、
    }   
    INT(INT X){見つける
        ?戻りP [X] == X X:Pは[X] =(P [X])を見つけます。
    } 
} TR。
int型のCNT;  
INT RT [MAXN]、LSON [MAXN * 10]、rson [MAXN * 10]、NUM [MAXN * 10]。      
ダブルデ[MAXN * 10]。
int型newnode(){ 
    リターン++ CNT。  
} 
ボイド押し上げ(INT X){ 
    NUM [X] = NUM [LS] + NUM [RS]。
    デ[X] =デ[LS] +ド[RS]。   
} 
ボイド更新(INT&X、int型のL、R INT、INT P、INT V){ 
    (!x)は、x = newnode()であれば、                    
    IF(L == R){ 
        NUM [X] + = V、デ[X] + =(ダブル)は、V *(ダブル)(ログ(P))。      
        返します。   
    } 
    INT半ば=(L + R)>> 1。       
    IF(p <= MID)更新(LS、L、中、P、V)。
    他の更新(RS、ミッド+ 1、R、P、V); 
    突き上げ(X)。
} 
int型のマージ(int型のx、int型のY){ 
    もしリターンX + Y(X || Y!)。   
    NUM [X] + = NUM [Y]。
    デ[X] + =デ[Y]。    
    LSON [X] =(LSON [X]、LSON [Y])をマージします。  
    rson [X] =マージ(rson [X]、rson [Y])。    
    Xを返します。
}     
以下(INT&X、int型のL、int型のR、int型K){int型
    (!X || L> = k)の場合はリターン0;   
    int型の再= 0; 
    (R <K){もし
        再= NUM [x]は、x = 0。
        再を返します。  
    }         
    IF(L == R)戻り0;   
    INT半ば=(L + R)>> 1。     
    (LS、L、中、K)+ =少ない再。
    + =以下(RS、ミッド+ 1、R、K)再。       
    突き上げ(X)。
    再を返します。     
} 
より大きい(INT&X、int型のL、int型のR、int型K){int型
    (!X || R <= K)であれば戻り0;  
    int型の再= 0; 
    IF(L> K){ 
        再= NUM [x]は、x = 0。
        再を返します。
    } 
    IF(L == R)戻り0; 
    INT半ば=(L + R)>> 1。
    + =大きく(LS、L、中、k)を再。
    + =大きく(RS、ミッド+ 1、R、K)再。
    突き上げ(X)。
    再を返します。   
} 
INT番目(int型のx、int型、L、のint R、int型K){      
    IF(L == R)戻りL。        
    INT半ば=(L + R)>> 1。   
    もし(K> NUM [LS])戻りk番目(RS、ミッド+ 1、R、K-NUM [LS])。
    それ以外の戻りk番目(LS、L、ミッド、K);        
} 
メインINT(){     
    使用して名前空間IO。  
    整数mを、CC = 0。  
    M = RD()。
    tr.init();    
    用(INT CAS = 1; CAS <= M; ++ CAS){ 
        int型のOP = RD()。
        IF(OP == 1){ 
            int型のx = RD()。  
            ++ CC;  
            アップデート(RT [CC]、1、N、X、1)。    
        } 
        IF(OP == 2){ 
            int型、X、Y、B。
            X = RD()、Y = RD()。
            = tr.find(X)、B = tr.find(Y)。        
            (!= B){場合
                RT [B] =マージ(RT [A]、RT [B])。            
                tr.p [A] Bを=。   
            } 
        }        
        (オペアンプ== 3){もし
            、X INT、C = 0。
            = RD()、X = RD()。
            = tr.find(A)。   
            C =以下(RT [A]、1、N、X)。         
            アップデート(RT [A]、1、N、X、C)。
        } 
        (OPの== 4){もし
            、X INT、C = 0。
            = RD()、X = RD()。
            = tr.find(A)。
            C =より大きい(RT [A]、1、N、X)。   
            アップデート(RT [A]、1、N、X、C)。       
        } 
        (OPの== 5){もし
            、K INT。  
            = RD()、K = RD()。
            = tr.find(A)。              
            printf( "%d個の\ n"、k番目(RT [A]、1、N、K))。   
        } 
        (オペアンプ== 6){もし           
            、B INT。
            = RD()、B = RD()。
            = tr.find(A)、B = tr.find(B)。      
            IF(デ[RT []]>ド[RT [B])のprintf( "1 \ n");
            他のprintf( "0 \ N"); 
        } 
        (OPの== 7){もし
            INT。
            = RD()。
            = tr.find(A)。
            printf( "%d個の\ n"、NUM [RT [A])。  
        } 
    }     
    0を返します。
}

  

おすすめ

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