Pagini recente » Cod sursa (job #1974828) | Cod sursa (job #387585) | Cod sursa (job #227538) | Diferente pentru home intre reviziile 792 si 793 | Cod sursa (job #2283984)
#include <bits/stdc++.h>
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
int n, m, k;
int lg[400002];
int rmq[20][400002];
int lvl[400002], first[100002];
int euler[400002];
vector<int>G[100002];
void dfs (int nod, int l) {
euler[++k] = nod;
lvl[k] = l;
first[nod] = k;
for (int i = 0; i < G[nod].size(); i++) {
dfs (G[nod][i], l + 1);
euler[++k] = nod;
lvl[k] = l;
}
}
void Rmq () {
for (int i = 1; i <= k; i++)
rmq[0][i] = i;
for (int i = 1; (1 << i) < k; i++)
for (int j = 1; j <= k - (1 << i) + 1; j++) {
int aux = 1 << (i - 1);
if (lvl[rmq[i - 1][j + aux]] < lvl[rmq[i - 1][j]])
rmq[i][j] = rmq[i - 1][j + aux];
else
rmq[i][j] = rmq[i - 1][j];
}
for (int i = 2; i <= k; i++)
lg[i] = lg[i / 2] + 1;
}
int lca (int x, int y) {
int st = first[x], dr = first[y];
if (st > dr)
swap(st, dr);
int dist = dr - st + 1;
int ans = rmq[lg[dist]][st];
int aux = dist - (1 << lg[dist]);
if (lvl[ans] > lvl[rmq[lg[dist]][st + aux]])
ans = rmq[lg[dist]][st + aux];
return euler[ans];
}
int main()
{
fin >> n >> m;
for (int i = 2; i <= n; i++) {
int x;
fin >> x;
G[x].push_back(i);
}
dfs(1, 0);
Rmq();
while (m--) {
int x, y;
fin >> x >> y;
fout << lca(x, y) << "\n";
}
return 0;
}