The key point of this question is that you can use a tree array: All query intervals do not contain each other, but may overlap.
In this way, you can add and delete edges from left to right using a tree array.
If there is an inclusion relationship, you cannot use a tree array. For the reason, see the sample data of poj 2104.
View code
# Include <cstdio> # Include <Cstring> # Include <Algorithm> Using Namespace STD; Const Int Maxn = 100010 ; Struct Node { Int Key, ID; Bool Operator <( Const Node & cm) Const { Return Key < Cm. Key ;}} dog [maxn]; Struct PP { Int L, R, kx, ID; Bool Operator <( Const PP & cm) Const { If (L! = Cm. l) Return L < Cm. L; Return R < Cm. r ;}} Q [maxn]; Int C [maxn], X [maxn], ran [maxn], ANS [maxn]; Void Update ( Int X, Int D ){ For (; X <maxn; x + = x &- X) C [x] + = D ;} Int Find_kth ( Int K ){ Int Ans = 0 , CNT = 0 , I; For (I = 20 ; I> = 0 ; I --) {Ans + = ( 1 < I ); If (ANS> = maxn | CNT + C [ANS]> = K) ans -= ( 1 < I ); Else CNT + = C [ANS];} Return Ans + 1 ;} Int Main (){ Int N, m, I, J, K, a, B; scanf ( " % D " , & N ,& M ); For (I = 1 ; I <= N; I ++ ) {Scanf ( " % D " ,& DOG [I]. Key); dog [I]. ID = I;} Sort (dog + 1 , Dog + 1 + N); X [ 1 ] = Dog [ 1 ]. Key; ran [DOG [ 1 ]. ID] = 1 ; For (J = 1 , I = 2 ; I <= N; I ++ ){ If (DOG [I]. Key! = Dog [I- 1 ]. Key) x [++ J] =DOG [I]. Key; ran [DOG [I]. ID] = J ;} For (I = 1 ; I <= m; I ++ ) {Scanf ( " % D " , & A, & B ,& K ); If (A> B) Swap (a, B); Q [I]. L = A; Q [I]. r = B; Q [I]. kx = K; Q [I]. ID = I;} Q [ 0 ]. L =1 ; Q [ 0 ]. R = 0 ; Sort (Q + 1 , Q + M + 1 ); For (I = 1 ; I <= m; I ++ ){ For (J = Q [I- 1 ]. L; j <= Q [I- 1 ]. R & J <q [I]. L; j ++ ) Update (ran [J], - 1 ); For (J = Q [I]. L <q [I- 1 ]. R + 1 ? Q [I- 1 ]. R + 1 : Q [I]. L; j <= Q [I]. R; j ++ ) Update (ran [J], 1 ); Int Num = Find_kth (Q [I]. kx); ans [Q [I]. ID] = X [num];} For (I = 1 ; I <= m; I ++) printf ( " % D \ n " , ANS [I]); Return 0 ;}