Pagini recente » Cod sursa (job #3199624) | Cod sursa (job #2639716) | Cod sursa (job #3032671) | Cod sursa (job #421727) | Cod sursa (job #2883201)
#include<bits/stdc++.h>
using namespace std;
ifstream fin ("lca.in");
ofstream fout("lca.out");
const int dim=200002;
int n,k,pos[dim],apr[dim],p[20];
vector<int>a[dim];
struct el
{
int nod,niv;
}rmq[20][dim];
void euler(int x,int tata,int h)
{
rmq[0][++k]={x,h};
pos[x]=k;
for (int y:a[x])
if (y!=tata)
{
euler(y,x,h+1);
rmq[0][++k]={x,h};
}
}
el mini (el a,el b)
{
if (a.niv<b.niv)
return a;
return b;
}
void precalc()
{
int put=1,exp=0;
p[0]=1;
for (int i=1;i<=k;i++)
{
apr[i]=exp;
if (p[exp]*2==i)
{
p[++exp]=2*put;
put*=2;
}
}
for (int i=1;i<=19;i++)
for (int j=1;j<=k-p[i]+1;j++)
rmq[i][j]=mini(rmq[i-1][j],rmq[i-1][j+p[i-1]]);
}
void query (int x,int y)
{
if (x>y)
swap(x,y);
int lg=y-x+1;
el lca=mini(rmq[apr[lg]][x],
rmq[apr[lg]][y-p[apr[lg]]+1]);
fout<<lca.nod<<'\n';
}
int main ()
{
int q,x,y;
fin>>n>>q;
for (int i=2;i<=n;i++)
{
fin>>x;
a[x].push_back(i);
a[i].push_back(x);
}
euler(1,0,1);
precalc();
while (q--)
{
fin>>x>>y;
query(pos[x],pos[y]);
}
}