Pagini recente » Cod sursa (job #2809139) | Cod sursa (job #968412) | Cod sursa (job #3127335) | Cod sursa (job #2700637) | Cod sursa (job #3003439)
#include <bits/stdc++.h>
#define MAX 100000
#define FILES freopen("lca.in","r",stdin);\
freopen("lca.out","w",stdout);
#define mod 666013
using namespace std;
int n, m, depth[MAX + 5], f[MAX + 5];
vector<int> v[MAX + 5];
vector<pair<int,int>> euler, rmq[24];
bool check[MAX + 5];
void dfs(int x, int d)
{
check[x] = 1;
depth[x] = d;
euler.push_back({x, depth[x]});
f[x] = euler.size() - 1;
for(auto i : v[x])
{
if(!check[i])
{
dfs(i, d + 1);
euler.push_back({x, depth[x]});
}
}
}
pair<int,int> ff(pair<int,int> a, pair<int,int> b)
{
return (a.second < b.second ? a : b);
}
pair<int,int> findLca(int a, int b)
{
int mn = min(f[a], f[b]), mx = max(f[a], f[b]), d = mx - mn + 1;
int p = 1,e = 0;
while(p * 2 < d)
p *= 2, e++;
return ff(rmq[e][mn], rmq[e][mx - p + 1]);
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
FILES
std::cin >> n >> m;
for(int i = 1;i < n; ++i)
{
int a;
std::cin >> a;
v[a].push_back(i + 1);
v[i + 1].push_back(a);
}
dfs(1, 1);
for(int i = 0;i < euler.size(); ++i)
rmq[0].push_back(euler[i]);
int p = log2(euler.size()), sz = euler.size();
for(int i = 1;i <= p; ++i)
{
sz -= (1 << (i - 1));
for(int j = 1;j <= sz; ++j)
rmq[i].push_back(ff(rmq[i - 1][j - 1], rmq[i - 1][j - 1 + (1 << (i - 1))]));
}
for(int i = 1;i <= m; ++i)
{
int a, b;
std::cin >> a >> b;
pair<int,int> rez = findLca(a, b);
std::cout << rez.first << '\n';
}
}