Pagini recente » Cod sursa (job #804730) | Cod sursa (job #736381) | Cod sursa (job #192909) | Cod sursa (job #2340932) | Cod sursa (job #3348583)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n,m;
vector<int> v[100003];
int parent[100003];
int rmq[200003][19];
int depth[100003];
int euler[200003];
int first[100003];
int timer;
void euler_tour(int nod,int tata,int nivel)
{
timer++;
first[nod]=timer;
euler[timer]=nod;
depth[nod]=nivel;
for (auto i:v[nod])
{
if (i==tata) continue;
euler_tour(i,nod,nivel+1);
timer++;
euler[timer]=nod;
}
}
int baza[200003];
void precalculare()
{
baza[1]=0;
for (int i=2;i<=timer;i++)
baza[i]=baza[i>>1]+1;
for (int i=1;i<=timer;i++)
rmq[i][0]=euler[i];
for (int j=1;j<=baza[timer];j++)
{
for (int i=1;i+(1<<j)-1<=timer;i++)
{
int left=rmq[i][j-1];
int right=rmq[i+(1<<(j-1))][j-1];
if (depth[left]<=depth[right]) rmq[i][j]=left;
else rmq[i][j]=right;
}
}
}
int lca(int x,int y)
{
int st=first[x];
int dr=first[y];
if (st>dr) swap(st,dr);
int j=baza[dr-st+1];
int left=rmq[st][j];
int right=rmq[dr-(1<<j)+1][j];
if (depth[left]<=depth[right]) return left;
return right;
}
int main()
{
fin>>n>>m;
for (int i=2;i<=n;i++)
{
fin>>parent[i];
v[parent[i]].push_back(i);
v[i].push_back(parent[i]);
}
euler_tour(1,0,1);
precalculare();
while (m--)
{
int x,y;
fin>>x>>y;
fout<<lca(x,y)<<'\n';
}
return 0;
}