Cod sursa(job #2907522)

Utilizator StanCatalinStanCatalin StanCatalin Data 30 mai 2022 16:44:12
Problema Range minimum query Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.41 kb
#include <iostream>
#include <fstream>
#include <stack>
#include <vector>
#include <map>
#include <cmath>

using namespace std;

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

const int dim = 100005;

pair<int, int> vec[dim];
int n, m, parinte[dim], _left[dim], _right[dim], index[dim], depth[dim];
map<int, int> poz;
vector<int> arbore[dim];

void calcul_cartezian() {
    stack<int> candidati;

    for (int i=1; i<=n; i++) {
        while (!candidati.empty() && vec[candidati.top()] > vec[i]) {
            candidati.pop();
        }
        if (candidati.empty()) {
            _left[i] = -1;
        } else {
            _left[i] = candidati.top();
        }
        candidati.push(i);
    }

    candidati = stack<int>();

    for (int i=n; i>=1; i--) {
        while (!candidati.empty() && vec[candidati.top()] > vec[i]) {
            candidati.pop();
        }
        if (candidati.empty()) {
            _right[i] = -1;
        } else {
            _right[i] = candidati.top();
        }
        candidati.push(i);
    }

    for (int i=1; i<=n; i++) {
        if (vec[_left[i]] <= vec[_right[i]]) {
            parinte[i] = _right[i];
        } else {
            parinte[i] = _left[i];
        }
//        parinte[i] = max(_left[i], _right[i]);
    }
}

void DFS(int nod) {
    int cnt = 0;
    for (auto y:arbore[nod]) {
        depth[y] = depth[nod] + 1;
        index[y] = 2 * index[nod] + cnt;
        poz[2 * index[nod] + cnt] = y;
        DFS(y);
        cnt++;
    }
}

int get_lca(int x, int y) {
    if (depth[x] > depth[y]) swap(x, y);

    int a = index[x];
    int b = index[y];

    int depth_diff = depth[y] - depth[x];
    if (depth_diff > 0) {
        b = (b>>depth_diff);
    }
    if (a == b) return a;
    int c = (a^b);

    int j = 0;
    for (int i=31; i>=0; i--) {
        if ((c&(1<<i)) != 0) {
            j = i;
            break;
        }
    }
    j++;
    return (a >> j);
}

int main() {
    in >> n >> m;
    for (int i=1; i<=n; i++) {
        in >> vec[i].first;
        vec[i].second = i;
    }
    calcul_cartezian();
    int root;
    for (int i=1; i<=n; i++) {
        if (parinte[i] == -1) root = i;
    }
    index[root] = 1;
    poz[1] = root;
    for (int i=1; i<=n; i++) {
        if (parinte[i] != -1) {
            arbore[parinte[i]].push_back(i);
        }
    }
    DFS(root);
    int x, y;
    while (m--) {
        in >> x >> y;
        out << vec[poz[get_lca(x, y)]].first << "\n";
    }
    return 0;
}