Chairman of the tree of knowledge finishing

Be persistent segment tree, alias Chairman of the tree.

In my opinion The beauty of this is that it is the data structure can be persistent concept for problem solving section of the query.

General Chairman of the tree is used to solve the big problems of the k interval.

We have established a tree line weights, weights segment tree is the i-th segment tree leaf nodes store i appeared many times (similar to bucket sort)

Hypothetical, a series of i-th element a [i] = p, the node insertion segment tree in the i th time, the concept may be persistent data structure is updated portion of each time node to establish a new node. For each time node, the root node must have been updated, therefore, a sequence of n elements, nodes interposed n time, there are n number of the root node.

Then, if desired [L, r] k-th largest, actually the root element in the set of nodes within the r time interval, and the elements under the root node l-1 times to make a difference set, then the process is similar to tree line in half query.

The specific method is, we l-1, and r is two times the root nodes out to see if they left subtree, set w = number of elements in the tree node r time left child node by subtracting the time of l-1 number of elements in the left subtree, if w> = k, then left recursive query k-th largest sub-tree, or the right sub-tree of the query kw large.

Chairman of the tree can solve the problem depends on what information stored in the tree line, but the general usage of the Chairman of the tree are more rigid, in addition to the first query interval k large, not many other uses.

#include <bits / STDC ++ H.>
 #define LL Long Long
 the using  namespace STD;
 const  int MAXN 1E5 + = 10 ;
 struct Node {
     int LS, RS, SUM;
     // left subtree, right subtree, the node value 
} NS [MAXN * 20 is ]; 
 
int CT;
 // time node 
int RT [MAXN * 20 is ];
 // RT [I] representative of a [i] in the tree are added in several 

void CPY ( int & now, int Old) { 
    now = ++ CT; 
    NS [now] = NS [Old]; 
}

void pushUp(int& now) {
    ns[now].sum = ns[ns[now].ls].sum + ns[ns[now].rs].sum;
}

void build(int& now, int l, int r) {
    now = ++ct;
    ns[now].sum = 0;
    if (l == r) return;
    int m = (l + r) >> 1;
    build(ns[now].ls, l, m);
    build(ns[now].rs, m + 1, r);
}

void update(int& now, intOld, int L, int R & lt, int X) { 
    CPY (now, Old); 
    // add a new tree in the old tree 
    IF (L == R & lt) { 
        NS [now] .sum ++ ;
         return ; 
    } 
    int m = (L + R & lt) >> . 1 ;
     IF (X <= m) Update (NS [now] .ls, NS [Old] .ls, L, m, X);
     the else Update (NS [now] .RS, NS [Old] .RS, m + . 1 , R & lt, X); 
    Pushup (now); 
    // update the weights up node 
} 

int Query ( int S, int T, int L,int r, int k) {
    if (l == r) return l;
    int m = (l + r) >> 1;
    int cnt = ns[ns[t].ls].sum - ns[ns[s].ls].sum;
    //cout << s << " " << t << " " << cnt << endl;
    if (k <= cnt) return query(ns[s].ls, ns[t].ls, l, m, k);
    return query(ns[s].rs, ns[t].rs, m + 1, r, k - cnt);
    // 
}

void init(int n) {
    ct = 0;
    build(rt[0], 1, The n-);
     // built from scratch Chairman tree 
}

 

Guess you like

Origin www.cnblogs.com/isakovsky/p/11312141.html