羅区P3224 [HNOI2012]ネバーランドセグメントツリーはテンプレートをマージ


質問の意味:
QクエリおよびK X小さい通信
Bは、2つのセットの通信なり
アプローチ:
小kの集合を見つける- >レンジセグメントツリーコレクション通信関係- >互いに素なセット合成コレクションを維持するために- >ツリーラインマージ
注:行ツリーの下に標準レンジセグメントツリーのノードIDが対応点ラベルの次のタイトルのために格納されている   
参照番号の点で返されたクエリ、およびLRは、対応する範囲である
。この問題は、離散必要とはならない小さな範囲の符号は、セグメントツリーの点における点範囲を区別します

#include <ビット/ STDC ++ H>
 使用して 名前空間STDを、
#define M 3100005
 の#define N 100005
 の#define半ば((L + R)>> 1)
 int型の和[M]、ID [M]、LS [M]、RS [M]、ndnum = 0 INT RT [N]、F [N]。
INT  GETINT X){ 場合(X == [X] F)リターン X。戻り F [X] = GET (F [X])。}
 ボイド更新(INT A){和[A] =和[LS [] + 和[RS []]。}
 INT(追加をintint型の L、INT R、INTPOS、INT IDX)
{ 
    IF(A)= A ++ ndnum ;! // これは、新しいポイントに直接ある
    IF(L == R&LT){ID [A] = IDX; SUM [A] ++; 返します;}
     IF(POS <= MID)LS [A] = 追加(LS [A]、L、MID、POS、IDX);
     他の RS [A]が追加=(RS [A]を、MID + 。1 、R&LT、POS、IDX)を; 
    更新(A); 
    返す; 
} 
int型マージ(int型int型 B、int型の L、INT R&LT)
{ 
    IF(!)戻り Bと、// ない直接返すの合計
    IF(B!)リターン;
     IF(L == R&LT){ID [A] = ID [B]、SUM [A] + = SUM [B]; 戻り A;} // 後述する再帰リーフノードと共通する部分には直接合計情報 
    LS [A] = マージ(LS [A]、LS [B]、L、MID); 
    RS [A] =マージ(RS [A]、RS [B]、MID + 1 、R&LT)、
    更新(A) ; 
    返す; 
} 
int型クエリ(INT S、int型の L、INT R&LT、INT K)を
{ 
    INT ANS;
     IF(K> SUM [S] || S!)戻り 0 ; // 公報文
    IF(R&LT == L )戻りID [S];
     IF(K <= SUM [LS [S])ANS = クエリ(LS [S]、L、MID、K);
      ANS =クエリ(RS [S]、MID + 1は、R、 - K- SUM [LS [S ]]);
     を返す; ANSを
} 
int型のmain()
{ 
    int型; N-、M、A、B、C、Q 
    scanfの(" %のDの%のD "、およびN-、&M);
     のためINT I = 1。 ;私は< N- =; I)がscanfの(++ " %のD "、&​​A)を、RT [I]は追加(RT [I]を、= 1、N-、A、Iは); // 各点は、最初のセグメントツリー有する
    ため(をint型私は= 1。 ; I <= N-; I ++)はF [I] =私は; // 互いに素セットを初期化するために覚えておく必要があります
    INT I = 1 ; I <= M、Iが++ ){ 
        scanfの(" %のDの%のD "、&​​B、&C);
         int型 X = GET(B)、Yは= GET (C); 
        F [Y] = X-; // と統合の方向に設定する必要があり、同じツリーラインをチェック!
        RT [X] =マージ(RT [X]、RT [Y]、1 、N-); 
    } 
    scanfの(" %のD "、&Q);
     一方、(Q - ){
         チャー OP [ 2 ]; 
        scanfの(" S%、OP); 
        scanfの(" %d個の%のD "、&​​B、&C);
         IF(OP [ 0 ] == ' Q ' ){
             int型 FA = GET(B); // 父親セグメントツリーのルートを見つけるために誰かを見つけます!
            INT ANS =クエリ(RT [FA]、1 、N末端、C);
             //は室温記述してください[FA]線分ツリー要素の代表点として参照により設定された番号で++なく自体よりndnum来る
            場合(!ANS)のprintf(" -1 \ N- " );
             のprintf(" %d個の\ N- " 、ANS); 
        } 
        そうでなければ{
             int型の FX = GET(B)、FY =GET (C);
             IF(FX == FY)続行; 
            F [FY] = FXを; // 2つのルートノードを見つけ、セグメントツリールートマージ 
            RT [FX] =マージを(RT [FX]、RT [FY] 1 )、N-; 
        } 
    } 
} 
/ * 
。5. 1 
4 3 2 5 1 
1 2 
。7 
Q 2 3 
Q 2 1 
B 2 3 
B. 5 1 
Q 2 1 
Q 2 4 
Q 2 3 
* /

 

おすすめ

転載: www.cnblogs.com/mowanying/p/11235951.html