Pagini recente » Cod sursa (job #1648911) | Cod sursa (job #2556015) | Cod sursa (job #947937) | Cod sursa (job #2584832) | Cod sursa (job #2984673)
#include <bits/stdc++.h>
using namespace std;
const int NMAX = 100004;
const int K = 17;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, m, q;
vector<int> adj[NMAX];
struct LowestCommonAncestor
{
vector<int> euler;
vector<bool> visited;
int height[NMAX];
int first[NMAX];
int st[NMAX][K];
int lg2[NMAX];
void dfs(int v)
{
visited[v] = true;
first[v] = euler.size();
euler.push_back(v);
for (int u : adj[v])
{
if (!visited[u])
{
height[u] = height[v] + 1;
dfs(u);
euler.push_back(v);
}
}
}
void precompute_lg2()
{
lg2[1] = 0;
for (int i = 2; i <= m; i++)
{
lg2[i] = lg2[i / 2] + 1;
}
}
void init_sparse_table()
{
precompute_lg2();
for (int i = 0; i < m; i++)
{
st[i][0] = euler[i];
}
for (int i = 1; i <= K; i++)
{
for (int j = 0; j + (1 << i) - 1 < m; j++)
{
st[j][i] = height[st[j][i - 1]] < height[st[j + (1 << (i - 1))][i - 1]] ? st[j][i - 1] : st[j + (1 << (i - 1))][i - 1];
}
}
}
void init()
{
height[1] = 1;
visited.assign(n + 1, false);
dfs(1);
m = euler.size();
init_sparse_table();
}
int get_min(int l, int r)
{
int lg = lg2[r - l + 1];
return height[st[l][lg]] < height[st[r - (1 << lg) + 1][lg]] ? st[l][lg] : st[r - (1 << lg) + 1][lg];
}
int lca(int u, int v)
{
int l = first[u];
int r = first[v];
if (r < l)
{
swap(l, r);
}
return get_min(l, r);
}
} 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;
}