Luo Gu P3224 [HNOI2012] Neverland segment tree merge templates


Meaning of the questions:
Q queries and communicating the k x small
B will be two sets communication
approach:
find a collection of small k -> range segment tree collection communicating relationship -> disjoint-set to maintain the combined collection -> Merge tree line
Note: line under the tree is a standard range segment tree node id is stored for the next title in the corresponding point label   
query is returned in the point of reference numbers, and lr is the corresponding range
of small range this question must not require discrete reference numeral distinguish point range in the segment tree points

#include<bits/stdc++.h>
using namespace std;
#define M 3100005
#define N 100005
#define mid ((l+r)>>1)
int sum[M],id[M],ls[M],rs[M],ndnum=0;
int rt[N],f[N];
int get(int x) { if(x==f[x]) return x; return f[x]=get(f[x]); }
void update(int a) { sum[a]=sum[ls[a]]+sum[rs[a]]; }
int add(int a,int l,int r,intPOS, int IDX) 
{ 
    IF (A) = A ++ ndnum;! // This is direct to a new point 
    IF (L == R & lt) {ID [A] = IDX; SUM [A] ++; return A;}
     IF (POS <= MID) LS [A] = the Add (LS [A], L, MID, POS, IDX);
     the else RS [A] = the Add (RS [A], MID + . 1 , R & lt, POS, IDX) ; 
    Update (a); 
    return a; 
} 
int Merge ( int a, int B, int L, int R & lt) 
{ 
    IF (a!) return B; // for a total of not return directly 
    IF (! B) returnA;
     IF (L == R & lt) {ID [A] = ID [B], SUM [A] + = SUM [B]; return A;} // recursive leaf node to be described and common parts total combined directly information 
    LS [A] = Merge (LS [A], LS [B], L, MID); 
    RS [A] = Merge (RS [A], RS [B], MID + . 1 , R & lt); 
    Update (A) ; 
    return A; 
} 
int Query ( int S, int L, int R & lt, int K) 
{ 
    int ANS;
     IF (! K> SUM [S] || S) return  0 ; // Laid sentence 
    IF (R & lt == L ) return ID [S];
     IF(K <= SUM [LS [S]]) ANS = Query (LS [S], L, MID, K);
     the else ANS = Query (RS [S], MID + . 1 , R & lt, - K- SUM [LS [S ]]);
     return ANS; 
} 
int main () 
{ 
    int n-, m, A, B, C, Q; 
    Scanf ( " % D% D " , & n-, & m);
     for ( int I = . 1 ; I < n-=; I ++) Scanf ( " % D " , & A), RT [I] = the Add (RT [I], . 1 , n-, A, I); // each point has an initial segment tree 
    for ( int I = . 1 ; I <= n-; I ++) F [I] = I; // disjoint-set must remember to initialize
    for ( int I = . 1 ; I <= m; I ++ ) { 
        Scanf ( " % D% D " , & B, & C);
         int X = GET (B), Y = GET (C); 
        F [Y] = the X-; // and check the direction of consolidation must be set and the same tree line! ! 
        RT [X] = Merge (RT [X], RT [Y], . 1 , n-); 
    } 
    Scanf ( " % D " , & Q);
     the while (Q - ) {
         char OP [ 2 ]; 
        Scanf ( " S% " , OP); 
        Scanf (" % D% D " , & B, & C);
         IF (OP [ 0 ] == ' Q ' ) {
             int FA = GET (B); // find someone to find his father segment tree root! ! 
            int ANS = Query (rt [fa], . 1 , n-, C);
             // be sure to write rt [fa] as the representative point of the line segment tree element in the set by reference numeral ++ come ndnum rather than itself 
            if (! ANS) the printf ( " -1 \ n- " );
             the else the printf ( " % D \ n- " , ANS); 
        } 
        the else {
             int FX = GET (B), FY =GET (C);
             IF (FX == FY) Continue ; 
            F [FY] = FX; // find two root nodes merged segment tree root 
            rt [fx] = merge (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 
* /

 

Guess you like

Origin www.cnblogs.com/mowanying/p/11235951.html