Pagini recente » Cod sursa (job #1490768) | Cod sursa (job #274971) | Cod sursa (job #2537288) | Cod sursa (job #2970305) | Cod sursa (job #2984649)
#include <bits/stdc++.h>
using namespace std;
const int NMAX = 100004;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, q;
vector<int> adj[NMAX];
struct LowestCommonAncestor
{
int height[NMAX];
int first[NMAX];
vector<int> euler;
int t[8 * NMAX];
vector<bool> visited;
void dfs(int v)
{
visited[v] = true;
first[v] = euler.size();
euler.push_back(v);
for (auto u : adj[v])
{
if (!visited[u])
{
height[u] = height[v] + 1;
dfs(u);
euler.push_back(v);
}
}
}
void build(int v, int tl, int tr)
{
if (tl == tr)
{
t[v] = euler[tl];
}
else
{
int tm = (tl + tr) / 2;
build(2 * v, tl, tm);
build(2 * v + 1, tm + 1, tr);
t[v] = (height[t[2 * v]] < height[t[2 * v + 1]]) ? t[2 * v] : t[2 * v + 1];
}
}
int query(int v, int tl, int tr, int l, int r)
{
if (r < l)
{
return -1;
}
if (tl == l && tr == r)
{
return t[v];
}
int tm = (tl + tr) / 2;
int l_ans = query(2 * v, tl, tm, l, min(tm, r));
int r_ans = query(2 * v + 1, tm + 1, tr, max(tm + 1, l), r);
if (l_ans == -1)
{
return r_ans;
}
if (r_ans == -1)
{
return l_ans;
}
return height[l_ans] < height[r_ans] ? l_ans : r_ans;
}
void init()
{
height[1] = 1;
visited.assign(n + 1, false);
euler.push_back(-1); // pt indexare de la 1
dfs(1);
build(1, 1, euler.size() - 1);
}
int lca(int u, int v)
{
int left = first[u];
int right = first[v];
if (left > right)
{
swap(left, right);
}
return query(1, 1, euler.size() - 1, left, right);
}
} LCA;
int main()
{
fin >> n >> q;
for (int i = 2; i <= n; i++)
{
int a;
fin >> a;
adj[a].push_back(i);
adj[i].push_back(a);
}
LCA.init();
for (int i = 1; i <= q; i++)
{
int a, b;
fin >> a >> b;
fout << LCA.lca(a, b) << '\n';
}
return 0;
}