Pagini recente » Monitorul de evaluare | Cod sursa (job #1070185) | Cod sursa (job #2504842) | Cod sursa (job #2462314) | Cod sursa (job #3321988)
#include <fstream>
#include <vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
int n,m;
vector<int> G[100005];
int niv[200005],E[200005],tint[100005],N;
int spt[20][200005],lg2[200005];
void dfs(int x,int tata,int h)
{
N++;
niv[N]=h;
E[N]=x;
tint[x]=N;
for(auto y:G[x])
{
if(y==tata) continue;
dfs(y,x,h+1);
N++;
E[N]=x;
niv[N]=h;
}
}
void rmq()
{
for(int i=2;i<=N;i++)
lg2[i]=1+lg2[i>>1];
int mxb=lg2[N];
for(int i=1;i<=N;i++)
spt[0][i]=i;
for(int i=1;i<=mxb;i++)
for(int j=1;j+(1<<i)-1<=N;j++)
{
int h1=spt[i-1][j];
int h2=spt[i-1][j+(1<<(i-1))];
if(niv[h1]<niv[h2])
spt[i][j]=h1;
else
spt[i][j]=h2;
}
}
int LCA(int x,int y)
{
int px=tint[x];
int py=tint[y];
if(py<px)
swap(py,px);
int sz=py-px+1;
int lg=lg2[sz];
int h1=spt[lg][px];
int h2=spt[lg][py-(1<<lg)+1];
if(niv[h1]<niv[h2])
return E[h1];
else
return E[h2];
}
int main()
{
cin>>n>>m;
for(int i=2;i<=n;i++)
{
int x;
cin>>x;
G[i].push_back(x);
G[x].push_back(i);
}
dfs(1,0,1);
rmq();
while(m--)
{
int x,y;
cin>>x>>y;
cout<<LCA(x,y)<<"\n";
}
return 0;
}