"Go" chairman tree: For each prefix of the sequence, build a line tree with the values in the sequence as subscript (so discretization), record the number of values that appear in the prefix sequence, and mark the 1~n as discrete; (the lower denomination is replaced directly with 1~n;)
For the value of section K of the interval [x, y], start with root[x-1],root[y], T=root[y]. [1,mid]-root[x-1]. [1,mid], t indicates that the number of values in the interval [x, y] at [1,mid] first determines whether T is greater than K.
If T is greater than k, then the number of [1,mid] in the interval [x, y] is greater than K, which is the value of k large in [1,mid], otherwise in [mid+1,r];
So we go down from root[x-1],root[y] in turn, when L==r, the value of K is the value that is marked L after discrete.
If each line segment is complete, n (n<<2) will definitely be mle, we find that for prefix [1,i] and prefix [1,i+1] segment tree, if B[i+1]<=mid (b[i+1] means a[i+1] discrete mark) Then the line tree I and the line segment tree i+1 the left side is exactly the same, no need to build, just need to use a pointer to point it out, so for a new line tree in fact, we have to build a maximum number of nodes is log (n), Nlog (n) node number is still tolerable;
1#include <cstdio>2#include <iostream>3#include <algorithm>4#include <cstring>5#include <cmath>6 using namespacestd;7 Const intMAXN =10000+Ten;8 Const intMaxnn = -*MAXN;9 intN, Q, MS, tot;Ten intROOT[MAXN], A[MAXN], Ls[maxnn], Rs[maxnn], s[maxnn]; One intNUM[MAXN], HASH[MAXN]; A intFindintx) { - intL =1, R =tot, M; - while(L <=R) { theM = L + R >>1; - if(Hash[m] < x) L = M +1; - ElseR = M-1; - } + returnL; - } + voidBuildintXint& Y,intLintRintv) { AS[y = + + ms] = S[x] +1; at if(L = = R)return; -Ls[y] = ls[x]; Rs[y] =Rs[x]; - intM = L + R >>1; - if(v <=m) build (Ls[x], ls[y], L, M, v); - ElseBuild (Rs[x], rs[y], M +1, R, v); - return ; in } - intQueryintXintYintLintRintk) { to if(L = = R)returnL; + intM = L + R >>1, KTH = S[ls[y]]-S[ls[x]]; - if(kth >= k)returnquery (Ls[x], ls[y], L, M, k); the Else returnQuery (Rs[x], rs[y], M +1, R, K-kth); * } $ voidReadint&x) {Panax Notoginsengx =0;intsig =1;CharCH =GetChar (); - while(!isdigit (CH)) {if(ch = ='-') sig =-1; CH =GetChar ();} the while(IsDigit (ch)) x =Ten* x + CH-'0', ch =GetChar (); +X *= sig;return ; A } the voidinit () { + read (n); read (Q); - for(inti =1; I <= N; i + +) read (A[i]), num[i] =A[i]; $Sort (num +1, num + n +1); hash[++ tot] = num[1]; $ for(inti =2; I <= N; i + +)if(Num[i]! = num[i-1]) hash[++ tot] = num[i]; - for(inti =1; I <= N; i + +) build (Root[i-1], Root[i],1, Tot, find (A[i])); - return ; the } - voidWork () {Wuyi int_i, _j, _k; the while(Q--){ - Read (_i); Read ( _j); Read (_k); Wuprintf"%d\n", Hash[query (Root[_i-1], Root[_j],1, Tot, _k)]); - } About return ; $ } - voidprint () { - - return ; A } + intMain () { the init (); - Work (); $ print (); the return 0; the}
Static Chairman Tree