Pagini recente » Cod sursa (job #1076659) | Cod sursa (job #1005350) | Cod sursa (job #1658671) | Cod sursa (job #186583) | Cod sursa (job #3149418)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, q;
vector<int> gf[100001];
int tata[100001], niv[100001];
int p_curent, p_start[100001], p_end[100001];
int stramos[18][100001];
void dfs(int nod, int nvl = 1) {
niv[nod] = nvl;
p_start[nod] = ++p_curent;
for (int fiu : gf[nod])
dfs(fiu, nvl + 1);
p_end[nod] = ++p_curent;
}
bool este_stramos(int x, int y) {
// return true <=> x este stramos al lui y
return p_start[x] <= p_start[y] && p_end[y] <= p_end[x];
}
void calculeaza_stramosi() {
for (int nod = 1; nod <= n; ++nod)
stramos[0][nod] = tata[nod];
for (int p = 1; p < 18; ++p) // p < MAX_LOG
for (int nod = 1; nod <= n; ++nod)
stramos[p][nod] = stramos[p - 1][stramos[p - 1][nod]];
}
int lca(int x, int y) {
if (este_stramos(x, y))
return x;
if (este_stramos(y, x))
return y;
for (int p = 17; p >= 0; p--) { // p = MAX_LOG - 1
int z = stramos[p][x];
if (z != 0 && !este_stramos(z, y))
x = z;
}
return stramos[0][x];
}
int main() {
fin >> n >> q;
for (int i = 2; i <= n; i++) {
fin >> tata[i];
gf[tata[i]].push_back(i);
}
p_curent = 0;
dfs(1);
calculeaza_stramosi();
for (int i = 1; i <= q; i++) {
int x, y;
fin >> x >> y;
fout << lca(x, y) << "\n";
}
return 0;
}