Pagini recente » Cod sursa (job #755964) | Istoria paginii runda/simulare_oji_2023_clasele_11_12_10_martie | Cod sursa (job #1619375) | Cod sursa (job #2868397) | Cod sursa (job #2880052)
// 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();
}