Pagini recente » Cod sursa (job #2870046) | Cod sursa (job #3306783) | Cod sursa (job #2686580) | Cod sursa (job #3210569) | Cod sursa (job #3352608)
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int NMAX = 1e5 + 1;
const int logNMAX = 41;
vector<int> fii[NMAX];
vector<int> euler, nivele, poz(NMAX);
int n, m;
int rmq[2 * NMAX][logNMAX];
void calculeazaMat(int n) {
for (int i = 0; i < n; i++) {
rmq[i][0] = i;
}
for (int j = 1; j <= log2(n); j++) {
for (int i = 0; i + (1 << j) <= n; i++) {
// rmq[i][j] = min(rmq[i][j - 1], rmq[i + (1 << (j - 1))][j - 1]);
if (nivele[rmq[i][j - 1]] < nivele[rmq[i + (1 << (j - 1))][j - 1]]) {
rmq[i][j] = rmq[i][j - 1];
}
else {
rmq[i][j] = rmq[i + (1 << (j - 1))][j - 1];
}
}
}
}
int query(int i, int j) {
if (i > j) {
swap(i, j);
}
int k = log2(j - i + 1);
return euler[nivele[rmq[i][k]] < nivele[rmq[j - (1 << k) + 1][k]] ? rmq[i][k] : rmq[j - (1 << k) + 1][k]];
}
void dfs(int node, int h) {
euler.push_back(node);
nivele.push_back(h);
poz[node] = euler.size() - 1;
for (const auto& i : fii[node]) {
dfs(i, h + 1);
euler.push_back(node);
nivele.push_back(h);
}
}
int main() {
fin >> n >> m;
for (int i = 2; i <= n; i++) {
int x;
fin >> x;
fii[x].push_back(i);
}
dfs(1, 0);
// for (auto i: euler) cout << i << " ";
// cout << "\n";
// for (auto i: nivele) cout << i << " ";
calculeazaMat(euler.size());
for (int i = 0; i < m; i++) {
int x, y;
fin >> x >> y;
fout << query(poz[x], poz[y]) << "\n";
}
}