Cod sursa(job #2880052)

Utilizator vladstefanVlad Oros vladstefan Data 29 martie 2022 13:09:55
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.68 kb

// problema LCA
// solutie de 100p

#include <iostream>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <deque>

using namespace std;

#define NMax 100000
#define LMax 200000
#define LogLMax 18

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

int n, m, t, level[NMax + 3], first[NMax + 3], last[NMax + 3];
pair<int, int> v[LMax + 3], rmq[LogLMax + 3][LMax + 3];
vector<int> fii[NMax + 3];

void input() {
    fin >> n >> m;
    for (int i = 2; i <= n; ++i) {
        fin >> t;
        fii[t].push_back(i);
    }
}

int ind, q;

void DFS(int st) {
    v[++ind] = {st, level[st]};
    first[st] = ind;
    for (auto f : fii[st]) {
        level[f] = level[st] + 1;
        DFS(f);
        v[++ind] = {st, level[st]};
    }
    last[st] = ind;
}

void init() {
    level[1] = 0;
    DFS(1);
    
    //
    
    for (int i = 1; i <= ind; ++i) rmq[0][i] = {v[i].second, v[i].first};
    for (int p = 1; p <= LogLMax; ++p) {
        q = 1 << p;
        for (int i = 1; i <= ind - q + 1; ++i) {
            if (rmq[p - 1][i].first < rmq[p - 1][i + q / 2].second) rmq[p][i] = rmq[p - 1][i];
            else rmq[p][i] = rmq[p - 1][i + q / 2];
        }
    }
}

pair<int, int> findminrange(int a, int b) {
    int p;
    a = first[a];
    b = last[b];
    for (p = 0; (1 << (p + 1)) <= (b - a + 1); ++p);
    if (rmq[p][a].first < rmq[p][b - (1 << p) + 1].first) return rmq[p][a];
    return rmq[p][b - (1 << p) + 1];
}

void solve() {
    int a, b;
    for (int j = 1; j <= m; ++j) {
        fin >> a >> b;
        fout << findminrange(a, b).second << '\n';
    }
}

int main() {
    input();
    init();
    solve();
}