Pagini recente » Cod sursa (job #1638728) | Cod sursa (job #2290285) | Cod sursa (job #2461737) | Cod sursa (job #1118119) | Cod sursa (job #3178151)
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int NMAX = 100001;
const int LMAX = 17;
vector<vector<int>> arbore;
vector<int> niveluri, turEuler, primaAparitie, lg(NMAX);
int rmq[LMAX][2 * NMAX], n, m;
void dfs(int nodCurent, int nivelCurent) {
primaAparitie[nodCurent] = turEuler.size();
turEuler.push_back(nodCurent);
niveluri.push_back(nivelCurent);
for (int copil : arbore[nodCurent]) {
dfs(copil, nivelCurent + 1);
turEuler.push_back(nodCurent);
niveluri.push_back(nivelCurent);
}
}
void calculeazaRMQ() {
for (int i = 0; i < turEuler.size(); i++)
rmq[0][i] = turEuler[i];
for (int i = 1; (1 << i) <= turEuler.size(); i++)
for (int j = 0; j + (1 << i) <= turEuler.size(); j++)
rmq[i][j] = min(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]);
}
int lca(int u, int v) {
int start = primaAparitie[u], end = primaAparitie[v];
if (start > end) swap(start, end);
int lungime = end - start + 1;
int k = lg[lungime];
return min(rmq[k][start], rmq[k][end - (1 << k) + 1]);
}
int main() {
fin >> n >> m;
arbore.resize(n + 1);
primaAparitie.resize(n + 1);
for (int nod = 2, parinte; nod <= n; nod++) {
fin >> parinte;
arbore[parinte].push_back(nod);
}
dfs(1, 0);
lg[1] = 0;
for (int i = 2; i <= n; i++)
lg[i] = lg[i / 2] + 1;
calculeazaRMQ();
for (int i = 0, u, v; i < m; i++) {
fin >> u >> v;
fout << lca(u, v) << '\n';
}
return 0;
}