Chairman of the tree initially

Pre-knowledge

  1. segment tree. . .

  (It did not seem

  2. (I do not know can be seen that it would be helpful) dynamic prescription segment tree

 Chairman of the tree (be persistent segment tree)

  A look can be persistent, we always think of some terrorist algorithms, but in fact is not difficult to understand, but here I just thought the Chairman of the tree to make it clear (as possible), title or brush their own (although I did not brush a few

  A look at the template title

Title Description

As stated, a given sequence of integers N, K a small value of the query within its specified range for the closed interval.

Input Format

The first line contains two positive integers N, M, respectively the length and the number of query sequences.

The second line contains N integers, indicates that the sequence number.

Next M lines contains three integers L, R & lt, kl to, R & lt, k L , R & lt , k, indicates that the query interval [L, R & lt] [L, R & lt] [ L , R & lt ] in the k-th smaller value.

Output Format

K comprising the result output lines, each an integer of 1, respectively for each query

  We found this question (in fact, can be used to write Splay difficult to deal with, because we did not learn what data structure can maintain a large range of k (balanced tree dalao can be ignored

  So how do you deal with this array is a key;

  Recall that we are seeking a prefix and when, and how to find a range? With a prefix and prefix and to reduce another.

  Analogy a bit, if we can get a range of minus another section of the k big?

  . Is incorporated herein, in a balanced tree operation, balanced tree left subtree of this node value is smaller than the maintenance subtree, right subtree of this node is larger than the maintenance value subtree ;

  How to balance the tree is operating it?

  Save each node sub-tree size, compare the size of ranking k and left subtree, ranked k is less than the size of the left subtree, so we are looking for a certain point in the left subtree, then go left subtree;

  If the ranking is larger than the left subtree, then the left subtree minus rankings and their own size, go right subtree

  

 

  Note that this must read!

  If you understand this concept, then it is simple. Consider segment tree is a binary tree, a tree with a balance in nature and the nature of the maintenance segment tree is the interval, then we consider the maintenance of a range segment tree.

  Then it can be a little early definition, Chairman of the tree is to maintain a range segment tree, each a position as a point in time, before inheriting a point, and add your own values.

  If the required interval of l to large r k, l then subtract segment tree with the time point r --1 point in time segment tree, then this interval to give a range in the number of how many, then with the above He said the practice is similar to the balance of the tree,

  (Figure I is not really draw out QAQ)

  To compensate, the code will be explained in detail

  Code

  

#include<bits/stdc++.h>
#define maxn 400007
using namespace std;
int n,m,tot,a[maxn],b[maxn];

template<typename type_of_scan>
inline void scan(type_of_scan &x){
    type_of_scan f=1;x=0;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    x*=f;
}
template<typename Tops,typename... tops>
inline void scan(Tops &x,tops&... X){
    scan(x),scan(X...);
}
template<typename type_of_print>
inline void print(type_of_print x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) print(x/10 ); 
    the putchar (X % 10 + ' 0 ' ); 
} 

struct Node {
     int L, R & lt, SUM; 
}; 

struct Tree { 
    Node TR [MAXN * 20 is ]; int T [MAXN >> . 1 ]; 
     void the Add ( int & RT, int pre, int L, int R & lt, int X) { 
        RT = TOT ++; // build a new point information stored 
        TR [RT] = TR [pre], TR [RT] .sum ++ ;
         // inherit the previous node, and add itself
        IF (r == L) return ;
         int MID = L + r >> . 1 ; // note here, l, and r is a range 
        IF (MID> = X) the Add (TR [RT] .L, TR [ pre] .L, L, MID, X);
         the else the Add (TR [RT] .r, TR [pre] .r, MID + . 1 , R & lt, X);
         // here we can see the advantages of the President of the tree, every build logn points 
    }
     // can be seen from it, each addition of only one new from root to leaf edge (other side is the front of the inheritance 
     // therefore space complexity nlogn, pay attention to an array of 
    int Query ( int U , int V, int L, int R & lt, int K) {
         IF (R & lt == L) return L;// return position 
        int MID = L + R & lt >> . 1 ;
         int X = TR [TR [V] .L] .sum- TR [TR [U] .L] .sum;
         // subtracting the elapsed time against forward in time,
         // get information section 
        IF (K <= X) return Query (TR [U] .L, TR [V] .L, L, MID, K);
         the else  return Query (TR [U]. R & lt, TR [V] .r, MID + . 1 , R & lt, - K- X);
         // similar to the operation of balanced tree 
    } 
} T; 

int main () { 
    Scan (n-, m); 
    for ( int I = . 1 ; I <= n-; I ++ ) 
        Scan (A [I]), B [I] =  A [I];
    Sort (B +. 1 , B + . 1 + n-);
     int OL = UNIQUE (B + . 1 , B + . 1 + n-)-b- . 1 ;
     for ( int I = . 1 ; I <= n-; I ++ ) { 
        A [I] = lower_bound (B + . 1 , B + . 1 + OL, a [I]) - B;
         // discretization 
        t.add (TT [I], TT [I- . 1 ], . 1 , OL, a [I]);
         // Note establish new when a node, before a period to inherit 
    } // do not contribute directly to the 
    for ( int I = . 1 , L, R & lt, K; I <= m; I ++ ) {
        scan(l,r,k);
        int pos=t.query(t.t[l-1],t.t[r],1,ol,k);
        printf("%d\n",b[pos]);
    }
    return 0;
}

 

to sum up  

  So probably finish the thought, here introduced a water problem , but to deepen the Chairman of the tree of great ideas to help (the Chairman of the tree as a prefix tree line)

  I will attach my code (code because we are not the same wind, if my code similar to the wind, it would look really enjoyed)

  Code

  

#include<bits/stdc++.h>
#define maxn 100007
using namespace std;
int n,m,fa[maxn],head[maxn],son[maxn],sz[maxn],ol;
int T[maxn],tot,a[maxn],top[maxn],dep[maxn],b[maxn];
int lastans,cent;
struct node{
    int next,to;
}edge[maxn<<1];
struct ML{
    int l,r,sum;
};

template<typename type_of_scan>
inline void scan(type_of_scan &x){
    type_of_scan f=1;x=0;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    x*=f;
}
template<typename Tops,typename... tops>
inline void scan(Tops &x,tops&... X){
    scan(x),scan(X...);
}
template<typename type_of_print>
inline void print(type_of_print x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) print(x/10);
    putchar(x%10+'0');
}

inline void add(int u,int v){
    edge[++cent]=(node){head[u],v};head[u]=cent;
    edge[++cent]=(node){head[v],u};head[v]=cent;
}

struct tree{
    ML tr[maxn*20];
    void add(int &rt,int pre,int l,int r,int x){
        rt=++tot;
        tr[rt]=tr[pre],tr[rt].sum++;
        if(l==r) return ;
        int mid=l+r>>1;
        if(x<=mid) add(tr[rt].l,tr[pre].l,l,mid,x);
        else add(tr[rt].r,tr[pre].r,mid+1,r,x);
    }
    int query(int u,int v,int lca,int flca,int l,int r,int k){
        if(l==r) return l;
        int mid=l+r>>1;
        int x=tr[tr[u].l].sum+tr[tr[v].l].sum-tr[tr[lca].l].sum-tr[tr[flca].l].sum;
        if(k<=x) return query(tr[u].l,tr[v].l,tr[lca].l,tr[flca].l,l,mid,k);
        else return query(tr[u].r,tr[v].r,tr[lca].r,tr[flca].r,mid+1,r,k-x);
    }
}t;

void dfs1(int x){
    sz[x]=1;t.add(T[x],T[fa[x]],1,ol,a[x]);
    for(int i=head[x];i;i=edge[i].next){
        int y=edge[i].to;
        if(y==fa[x]) continue;
        fa[y]=x;dep[y]=dep[x]+1;
        dfs1(y);sz[x]+=sz[y];
        if(sz[son[x]]<sz[y]) son[x]=y;
    }
}

void dfs2(int x,int tp){
    top[x]=tp;
    if(!son[x]) return ;
    dfs2(son[x],tp);
    for(int i=head[x];i;i=edge[i].next){
        int y=edge[i].to;
        if(y==fa[x]||y==son[x]) continue;
        dfs2(y,y);
    }
}

int get_lca(int x,int y){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        x=fa[top[x]];
    }
    return dep[x]<dep[y]?x:y;
}

int main(){
    scan(n,m);
    for(int i=1;i<=n;i++) scan(a[i]),b[i]=a[i];
    sort(b+1,b+1+n);
    ol=unique(b+1,b+1+n)-b-1;
    for(int i=1;i<=n;i++)
        a[i]=lower_bound(b+1,b+1+ol,a[i])-b;
    for(int i=1,u,v;i<=n-1;i++)
        scan(u,v),add(u,v);
    dfs1(1),dfs2(1,1);
    for(int i=1,u,v,k;i<=m;i++){
        scan(u,v,k);u^=lastans;
        int lca=get_lca(u,v);
        int pos=t.query(T[u],T[v],T[lca],T[fa[lca]],1,ol,k);
        printf("%d\n",b[pos]);lastans=b[pos];
    }
}

If you have read this blog and scold Bo speaker too simple, that you have gone beyond the QAQ blogger

 

end 

 

Guess you like

Origin www.cnblogs.com/waterflower/p/11354029.html