Pagini recente » Cod sursa (job #701222) | Cod sursa (job #704438) | Cod sursa (job #3303995) | Cod sursa (job #408606) | Cod sursa (job #3311121)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
void dfs(int nod, int nivel);
void precalc();
int lca(int st, int dr);
int n, m, euler_size;
vector<pair<int, int>> euler;
vector<int> copii[100002];
pair<int, int> rmq[400002][20]; //.first = nivel, .second = nod
int first[100002], lg2[400002];
bool apare[100002];
int main()
{
fin>>n>>m;
for(int i = 1; i <= n-1; ++i)
{
int nod;
fin>>nod;
copii[nod].push_back(i+1);
}
dfs(1, 0);
precalc();
for(int i = 1; i <= m; ++i)
{
int x, y;
fin>>x>>y;
x = first[x];
y = first[y];
if(x > y)
swap(x, y);
fout<<lca(x, y)<<"\n";
}
return 0;
}
int lca(int st, int dr)
{
int l = lg2[dr - st + 1];
pair<int, int> rez = min(rmq[st][l], rmq[dr - (1<<l) + 1][l]);
return rez.second;
}
void precalc()
{
for(int i = 2; i <= euler_size; ++i)
lg2[i] = lg2[i/2] + 1;
for(int i = 0; i < euler_size; ++i)
rmq[i][0] = {euler[i].first, euler[i].second};
for(int i = 1; (1<<i) < euler_size; ++i)
{
for(int j = 0; j + (1<<i) <= euler_size; ++j)
{
rmq[j][i] = min(rmq[j][i-1], rmq[(1<<(i-1)) + j][i-1]);
}
}
}
void dfs(int nod, int nivel)
{
++euler_size;
euler.push_back({nivel, nod});
if(!apare[nod])
{
apare[nod] = true;
first[nod] = euler_size - 1;
}
for(auto i : copii[nod])
{
dfs(i, nivel+1);
++euler_size;
euler.push_back({nivel, nod});
}
}