Topic link HDU-2665 Kth number topic effect
Given the sequence of n N, the number of M-m queries, each interval [l,r] [l,r] of the K-K decimal. Sample Input
1
10 1
1 4 2 3 5 6 7 8 9 0
1 3 2 Sample Output
2 Ideas
K K big problem in the interval has not been, first learned to divide the tree, although run quickly, but change the query interval part of a bit around, easy to write wrong, and can only be used to not modify the interval K K big problem, it is estimated that the game will not be used.
I learned a little bit about the persistence of the line-segment tree, and found that the leaf node of the line tree is the weight, not the usual interval.
At the time of establishment, a weighted segment tree is established for all the intervals of [1,i] [1,i], and the corresponding segment tree is root[i] root[i], so that the segment tree l,r when the query interval [l,r] [root[r]−root[l−1] is root[r]-root[l-1] is the number of times each value of the interval [l,r] [L,r] appears, and then it is easy to query the K K of the interval.
At the time of achievement, the log (n) log (n) node will be changed at every single path to the root to the leaf node. The other nodes are invariant, so each time only increases the change node, the other nodes point to the corresponding node of the previous tree, the space complexity is Nlogn nlogn. Code
#include <cstdio> #include <cstring> #include <algorithm> using namespace std;
/* Sustainable segment tree-query interval k small "query interval k large, that is, the query interval r-l+1-k+1=r-l+2-k small" initialization: A[1..N] for the original sequence, SORTED[1..N] for the original sequence of the backup, and then call build on the line
Hash after the value of the current number of the first occurrence of the subscript, so there is a partial subscript no corresponding value, but relatively simple/const int maxn=100007; const int LOGMAXN=19;//100 000 number 19 is enough.//The Sustainable segment tree is a weighted segment tree, that is, the interval is the weight, and the interval independent of the original sequence//I number is the weight line segment tree struct Node {///that is established by the original sequence interval [1,i].
In order to prevent the MLE, the segment tree node does not save the interval endpoint, but dynamically obtains the int lson,rson;
int sum;//sum Indicates the number of weights and}TR[MAXN*LOGMAXN];
int n; int A[MAXN],SORTED[MAXN];//A[1..N] represents the original sequence, SORTED[1..N] indicates that the sorted sequence int root[maxn],cnt;//cnt represents the currently used knot number void Inser (int & Cur,int ori,int val,int l=1,int r=n) {//cur Indicates the number of the current line segment tree "Call is incoming Root[i]", the Ori passed in Root[i-1], Val is the weight cur=cnt++;//
Assigning a new node to the current node Tr[cur]=tr[ori];
After the ++tr[cur].sum;//is inserted into the Val, the new node sum+1 if (l==r) {return;
int mid= (L+R) >>1;
if (val<=mid) {inser (tr[cur].lson,tr[ori].lson,val,l,mid); else {inser (tr[cur].rson,tr[ori].rson,val,mid+1,r);
} int query (int l,int r,int k,int l=1,int r=n) {//l,r indicates that the subscript of the line segment tree represented by the left and right endpoints of the query interval is "call is passed in ROOT[LL-1],ROOT[RR]" if (l==r
) {return l; The int tmp=tr[tr[r].lson].sum-tr[tr[l].lson].sum,mid= (L+R) >>1;//calculates the number of first half weights in the query interval if (k<=tmp) {R
Eturn query (TR[L].LSON,TR[R].LSON,K,L,MID);
return query (TR[L].RSON,TR[R].RSON,K-TMP,MID+1,R); void Build () {//Initialize and establish a sustainable segment tree tr[0].lson=tr[0].rson=tr[0].sum=root[0]=0;//since lson,rson,sum values will not be changed (child nodes or themselves),
Therefore, only one root node can represent an empty number cnt=1;
Sort (sorted+1,sorted+1+n); for (int i=1;i<=n;++i) {Inser (Root[i],root[i-1],lower_bound (sorted+1,sorted+1+n,a[i))-sorted);//This hash will have part subscript no right
The number due, but relatively simple}} int m,l,r,k;
int main () {int T;
scanf ("%d", &t);
while (t-->0) {scanf ("%d%d", &n,&m);
for (int i=1;i<=n;++i) {scanf ("%d", a+i);
Sorted[i]=a[i];
Build (); while (m-->0) {scanf ("%d%d%d"), &l,&r, &k);
printf ("%d\n", Sorted[query (Root[l-1],root[r],k));/note returns the subscript}} return 0; }