Pagini recente » Cod sursa (job #1646477) | Cod sursa (job #2699307) | Borderou de evaluare (job #2243312) | Cod sursa (job #2776651) | Cod sursa (job #2981711)
#include <bits/stdc++.h>
using namespace std;
string np = "lca";
ifstream f(np + ".in");
ofstream g(np + ".out");
// #define f cin
// #define g cout
int n, m, len, nivel[100003], rmq[20][200009], first[100003];
pair<int, int> w[200003];
vector<int> adj[100003];
void dfs(int nod)
{
w[++len].first = nod;
w[len].second = nivel[nod];
if (!first[nod])
first[nod] = len;
for (auto next : adj[nod])
if (!nivel[next])
nivel[next] = nivel[nod] + 1, dfs(next),
w[++len].first = nod, w[len].second = nivel[nod];
}
void build_rmq()
{
for (int i = 1; i <= len; i++)
rmq[0][i] = i;
for (int i = 1, pd = 1; (1 << i) <= len; i++, pd <<= 1)
for (int j = 1; j + (1 << i) - 1 <= len; j++)
if (w[rmq[i - 1][j]].second < w[rmq[i - 1][j + pd]].second)
rmq[i][j] = rmq[i - 1][j];
else
rmq[i][j] = rmq[i - 1][j + pd];
}
int query(int a, int b)
{
a = first[a];
b = first[b];
if (a > b)
swap(a, b);
int t = log2(b - a + 1);
if (w[rmq[t][a]].second < w[rmq[t][b - (1 << t) + 1]].second)
return w[rmq[t][a]].first;
return w[rmq[t][b - (1 << t) + 1]].first;
}
int main()
{
f >> n >> m;
for (int i = 2, a; i <= n; i++)
f >> a, adj[a].emplace_back(i), adj[i].emplace_back(a);
nivel[1] = 1;
dfs(1);
build_rmq();
for (int a, b; m; m--)
f >> a >> b, g << query(a, b) << '\n';
return 0;
}