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 * /