Pagini recente » Cod sursa (job #985943) | Cod sursa (job #121119) | Cod sursa (job #2347725) | Cod sursa (job #559733) | Cod sursa (job #1882866)
#include <bits/stdc++.h>
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
const int maxn = 1e5 + 5;
vector <int> G[maxn];
int minn, ans, m;
int Euler[maxn << 1], Lev[maxn << 1], T[maxn << 2], First[maxn];
void Dfs (int node, int lev) {
Euler[++m] = node;
Lev[m] = lev;
First[node] = m;
for (auto &it : G[node]) {
Dfs(it, lev + 1);
Euler[++m] = node;
Lev[m] = lev;
}
}
inline int Unite (int x, int y) {
if (Lev[x] <= Lev[y]) return x;
return y;
}
void Build () {
int i;
for (i = 1; i <= m; i++) {
T[i + m - 1] = i;
}
for (i = m - 1; i > 0; i--) {
T[i] = Unite(T[i << 1], T[i << 1 | 1]);
}
}
inline void Get_sol (int x) {
if (Lev[x] < minn) {
minn = Lev[x];
ans = Euler[x];
}
}
void Query (int left, int right) {
left += m;
right += m;
while (left < right) {
if (left & 1) Get_sol(T[left++]);
if (right & 1) Get_sol(T[--right]);
left >>= 1;
right >>= 1;
}
}
int Lca (int x, int y) {
int a = First[x];
int b = First[y];
if (a > b) swap(a, b);
minn = (1 << 30);
Query(a - 1, b);
return ans;
}
int main () {
ios_base :: sync_with_stdio (false);
int n, q, i, x, y;
fin >> n >> q;
for (i = 2; i <= n; i++) {
fin >> x;
G[x].push_back(i);
}
Dfs(1, 1);
Build();
while (q--) {
fin >> x >> y;
fout << Lca(x, y) << '\n';
}
fin.close();
fout.close();
return 0;
}