Cod sursa(job #2282682)

Utilizator laurageorgescuLaura Georgescu laurageorgescu Data 14 noiembrie 2018 12:26:27
Problema Range minimum query Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.57 kb
// rmq offline in Nlog*

#include <bits/stdc++.h>

using namespace std;

ifstream fin ("rmq.in"); ofstream fout ("rmq.out");

const int nmax = 1e5;
const int mmax = 1e6;

pair<int, int> st[nmax + 1];

struct str {
    int x, y, ind;

    bool operator < (const str &shp) const {
        return y < shp.y;
    }
} q[mmax + 1];
int rasp[mmax + 1];

struct dsu {
    int tata[nmax + 1], grad[nmax + 1], mnval[nmax + 1];

    int find_tata (int x) {
        if (x == tata[x]) return x;
        return tata[x] = find_tata(tata[x]);
    }

    void unite (int x, int y) {
        x = find_tata(x); y = find_tata(y);
        if (x == y)
            return ;

        if (grad[x] < grad[y])
            swap(x, y);

        grad[x] += grad[y];
        tata[y] = x;
        mnval[x] = min(mnval[x], mnval[y]);
    }
} p;

int main() {
    int n, m;
    fin >> n >> m;

    for (int i = 1; i <= n; ++ i) {
        fin >> p.mnval[i];
        p.tata[i] = i;
        p.grad[i] = 1;
    }

    for (int i = 1; i <= m; ++ i) {
        fin >> q[i].x >> q[i].y;
        q[i].ind = i;
    }

    sort(q + 1, q + m + 1);

    int top = 0, ind = 1;
    for (int i = 1; i <= n; ++ i) {
        int val = p.mnval[i];
        while (top > 0 && st[top].first >= val) {
            p.unite(i, st[top].second);
            -- top;
        }

        st[++ top] = {val, i};

        while (ind <= m && q[ind].y == i) {
            rasp[q[ind].ind] = p.mnval[p.find_tata(q[ind].x)];
            ++ ind;
        }
    }

    for (int i = 1; i <= m; ++ i)
        fout << rasp[i] << "\n";

    fin.close();
    fout.close();
    return 0;
}