Cod sursa(job #2383994)

Utilizator retrogradLucian Bicsi retrograd Data 19 martie 2019 22:33:31
Problema Range minimum query Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.69 kb
#include <bits/stdc++.h>

using namespace std;

struct Query {
    int l, r, idx;
    bool operator<(const Query& oth) const {
        if (l != oth.l) 
            return l < oth.l;
        return r < oth.r;
    }
};

vector<Query> queries;
vector<int> values, start, stop, ans, dp;

void Divide(int b, int e) {
    if (b == e) {
        int& at = start[b];
        while (at != stop[b] && queries[at].r == b) {
            ans[queries[at].idx] = values[b];
            ++at;
        }
        return;
    }

    int m = (b + e) / 2;
    Divide(b, m);
    Divide(m + 1, e);
    
    dp[m] = values[m];
    for (int i = m - 1; i >= b; --i)
        dp[i] = min(values[i], dp[i + 1]);
    dp[m + 1] = values[m + 1];
    for (int i = m + 2; i <= e; ++i)
        dp[i] = min(values[i], dp[i - 1]);
    for (int i = b; i <= m; ++i) {
        int& at = start[i];
        while (at != stop[i] && queries[at].r <= e) {
            ans[queries[at].idx] = min(dp[i], dp[queries[at].r]);
            ++at;
        }
    }
}

int main() {
    ifstream cin("rmq.in");
    ofstream cout("rmq.out");

    int n, m; cin >> n >> m;
    queries.resize(m);
    values.resize(n);
    for (int i = 0; i < n; ++i) 
        cin >> values[i];
    
    for (int i = 0; i < m; ++i) {
        auto& q = queries[i];
        cin >> q.l >> q.r; --q.l; --q.r;
        q.idx = i;
    }
    
    sort(queries.begin(), queries.end());
    start.resize(n, -1); stop.resize(n, -1);
    for (int i = 0; i < m; ++i) {
        const auto& q = queries[i];
        if (start[q.l] == -1) 
            start[q.l] = i;
        stop[q.l] = i + 1;
    }   
    
    ans.resize(m);
    dp.resize(n);
    Divide(0, n - 1);
    for (auto x : ans)
        cout << x << '\n'; 
}