Luo Gu [P4137] Rmq Problem / mex (Chairman of the tree)

Topic Link
easy to find, the answer may be only \ (0 \) , each number, each number \ (+ 1 \)
then put the \ (2n + 1 \) the number of weights to build a tree line, it may persist each node records this subtree and finally adding the number of added time minimum \ (Latest \) (a good understanding of it).
For queries \ ((L, r) \) , binary tree line to find the smallest (latest <l \) \ leaf node, then the answer is the number of the node represents.

#include <cstdio>
#include <cmath>
#include <algorithm>
#define INF 2147483647;
using namespace std;
inline int read(){
    int s = 0;
    char ch = getchar();
    while(ch < '0' || ch > '9') ch = getchar();
    while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); }
    return s;
}
const int MAXN = 200010;
const int MAXNLOGN = 10000010;
struct SegTree{
    int lc, rc, latest;
}t[MAXNLOGN];
int cnt, root[MAXN], n, m, a, b;
int val[MAXN], s[MAXN], num;
inline void pushup(int x){
    t[x].latest = min(t[t[x].lc].latest, t[t[x].rc].latest);
}
int update(int x, int l, int r, int c, int d){
    int id = ++cnt; t[id] = t[x];
    if(l == r){ t[id].latest = d; return id; }
    else{
        int mid = (l + r) >> 1;
        if(c <= mid) t[id].lc = update(t[x].lc, l, mid, c, d);
        else t[id].rc = update(t[x].rc, mid + 1, r, c, d);
        pushup(id); return id;
    }
}
int query(int x, int l, int r, int c){
    if(l == r) return val[l];
    int mid = (l + r) >> 1;
    if(t[t[x].lc].latest < c) return query(t[x].lc, l, mid, c);
    else if(t[t[x].rc].latest < c) return query(t[x].rc, mid + 1, r, c);
    return val[num] + 1;
}
struct lsh{
    int val, id;
    int operator < (const lsh A) const{
        return val < A.val;
    }
}p[MAXN];
int build(int l, int r){
    int id = ++cnt;
    if(l == r) return id; 
    int mid = (l + r) >> 1;
    t[id].lc = build(l, mid);
    t[id].rc = build(mid + 1, r);
    pushup(id); return id;
}
int main(){
    n = read(); m = read();
    for(int i = 1; i <= n; ++i)
        p[i].val = read(), p[i].id = i;
    sort(p + 1, p + n + 2); 
    for(int i = 1; i <= n + 1; ++i){
        s[p[i].id] = (p[i].val == p[i - 1].val ? num : ++num);
        val[num] = p[i].val;
    }
    root[0] = build(1, num);
    for(int i = 1; i <= n; ++i)
        root[i] = update(root[i - 1], 1, num, s[i], i);
    for(int i = 1; i <= m; ++i){
        a = read(); b = read();
        printf("%d\n", query(root[b], 1, num, a));
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/Qihoo360/p/11027940.html