Pagini recente » Cod sursa (job #1232991) | Cod sursa (job #882227) | Cod sursa (job #865288) | Cod sursa (job #1839720) | Cod sursa (job #2989814)
#include <bits/stdc++.h>
#pragma GCC optimize("fast-math")
#define ll long long
using namespace std;
int main(void)
{
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
ios :: sync_with_stdio(false);
cin.tie(nullptr);
int n, q;
cin >> n >> q;
vector<vector<int>> cv(n + 1);
for (int i = 2, x; i <= n; i++)
{
cin >> x;
cv[x].push_back(i);
}
vector<int> euler(1, 0), level(1, 0);
vector<int> time_in(n + 1, 0);
int lvl = -1;
function<void(int)> dfs = [&](int v)
{
++lvl;
euler.push_back(v);
level.push_back(lvl);
for (int u : cv[v])
{
dfs(u);
euler.push_back(v);
level.push_back(lvl);
}
--lvl;
};
dfs(1);
int m = euler.size() - 1;
for (int i = 1; i <= m; i++)
if (time_in[euler[i]] == 0)
time_in[euler[i]] = i;
vector<vector<pair<int, int>>> rmq(log2(m) + 1, vector<pair<int, int>>(m + 1, make_pair(0, 0)));
for (int i = 1; i <= m; i++)
{
rmq[0][i].first = level[i];
rmq[0][i].second = euler[i];
}
for (int bit = 1, z = 2; z <= m; bit++, z *= 2)
for (int j = 1; j + z - 1 <= m; j++)
{
rmq[bit][j] = min(rmq[bit - 1][j], rmq[bit - 1][j + z / 2]);
}
function<pair<int, int>(int, int)> query = [&](int x, int y)
{
int dist = y - x + 1;
int bit = log2(dist);
int z = (1 << bit);
return min(rmq[bit][x], rmq[bit][y - z + 1]);
};
function<int(int, int)> LCA = [&](int v, int u)
{
return query(min(time_in[v], time_in[u]), max(time_in[v], time_in[u])).second;
};
for (int que = 1, v, u; que <= q; que++)
{
cin >> v >> u;
cout << LCA(v, u) << '\n';
}
return 0;
}