RMQ / mex

The meaning of problems

A given length \ (n-\) sequences have \ (m \) a query, each query \ ([l, r] \ ) of a section through the not occur within the minimum natural number (i.e., the range required the \ (MEX \) )


solution

And \ (\ tt {CCPC} \ ) a second network synchronization title race \ (\ tt {array} \ ) like

Also the achievements of weights, each weight value is saved a location

But the difference is that it is a question of a guarantee arrangement, that is, \ ([1, n] \ ) Each number appears at most once and will appear once

This question and does not guarantee that this is a permutation

Therefore, we consider the use of the Chairman of the tree, interval contribution for each prefix

At a time when saved each position is that the number of position last occurrence

Such benefits are obvious, if for \ ([1, R] \ ) prefix, the position of the last occurrence of a number we find if \ ([L, R] \ ) between, then it must not legitimate

We hold parent-child relationship in the position of minimum

For each \ ([L, R] \ ) of this section, we first \ (R & lt \) pieces of line segment tree query

If the weight of the left subtree is less than \ (L \) , instructions left subtree must have a legitimate answer, right subtree empathy

There is also a need to pay attention:

Because the answer each query will not exceed \ (n \) , so we can not discrete, for greater than \ (n \) data can not inserted

To facilitate the process, the number of all are added \ (1 \) to avoid a weight of \ (0 \) case, minus the query back

Can compare this title with \ (\ tt {array} \ )

Why is this question in the tree line to get \ (min \) , and that you want to take a \ (max \) ?

Because of that problem, the legal position is at one end of the large, and different this topic


Code

#include <iostream>
#include <cstdio>

using namespace std;

void fast_IO();

const int N = 2e5 + 10;

int n, m;
int rt[N];

struct CTree {
    
    int sz;
    int ls[N * 20], rs[N * 20], val[N * 20];
    
    void clear() { sz = 0; }
    
    int newnode() {
        ++sz;
        ls[sz] = rs[sz] = val[sz] = 0;
        return sz;  
    }
    
    void mkchain(int &x, int y, int l, int r, int k, int v) {
        x = newnode();
        ls[x] = ls[y], rs[x] = rs[y];
        if (l == r) return val[x] = v, void();
        int mid = l + r >> 1;
        if (k <= mid)
            mkchain(ls[x], ls[y], l, mid, k, v);
        else
            mkchain(rs[x], rs[y], mid + 1, r, k, v);
        val[x] = min(val[ls[x]], val[rs[x]]);
    }
    
    int query(int x, int l, int r, int k) {
        if (l == r) return l - 1;
        int mid = l + r >> 1;
        if (val[ls[x]] < k)
            return query(ls[x], l, mid, k);
        else 
            return query(rs[x], mid + 1, r, k);
    }
    
} tr;

int main() {
    
    fast_IO();
    tr.clear();
    
    cin >> n >> m;
    
    int x, y;
    for (int i = 1; i <= n; ++i) {
        cin >> x;
        tr.mkchain(rt[i], rt[i - 1], 1, n + 1, x + 1, i);   
    }
    
    for (int i = 1; i <= m; ++i) {
        cin >> x >> y;
        cout << tr.query(rt[y], 1, n + 1, x) << endl;   
    }
    
    return 0;
}

void fast_IO() {
    ios :: sync_with_stdio(false);
    cin.tie(NULL), cout.tie(NULL);  
}

Guess you like

Origin www.cnblogs.com/VeniVidiVici/p/11459928.html