Pagini recente » Cod sursa (job #2106508) | Cod sursa (job #518949) | Cod sursa (job #1337898) | Cod sursa (job #1233845) | Cod sursa (job #2922066)
#include<bits/stdc++.h>
#define int long long
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int n,m,w[100005],nivel[100005],k,e[200005],p[200005],ap[200005];
vector<int>v[100005];
struct elem
{
int x,niv;
};
elem nou[2*100005];
elem rmq[20][2*100005];
void dfs(int nod)
{
nivel[nod]=nivel[w[nod]]+1;
k++;
nou[k].x=nod;
nou[k].niv=nivel[nod];
for(auto it:v[nod])
{
dfs(it);
k++;
nou[k].x=nod;
nou[k].niv=nivel[nod];
}
}
void rmqprecalc()
{
int i,x,k1;
for(i=1;i<=k;i++)
rmq[0][i]=nou[i];
x=1,k1=0;
for(i=1;i<=k;i++)
{
if(i==2*x)
{
k1++;
x*=2;
}
e[i]=k1;
p[k1]=x;
}
x=2;k1=1;
while(x<=n)
{
for(i=1;i<=k-x+1;i++)
{
if(rmq[k1-1][i].niv<rmq[k1-1][i+x/2].niv)
rmq[k1][i]=rmq[k1-1][i];
else
rmq[k1][i]=rmq[k1-1][i+x/2];
}
k1++;
x*=2;
}
}
int lca(int x, int y)
{
x=ap[x];
y=ap[y];
if(x>y)
swap(x,y);
int l=y-x+1;
if(rmq[e[l]][x].niv<rmq[e[l]][y-p[e[l]]+1].niv)
return rmq[e[l]][x].x;
else
return rmq[e[l]][y-p[e[l]]+1].x;
}
signed main()
{
int i,x,y;
f>>n>>m;
for(i=2;i<=n;i++)
{
f>>w[i];
v[w[i]].push_back(i);
}
dfs(1);
rmqprecalc();
for(i=1;i<=k;i++)
{
if(ap[nou[i].x]==0)
ap[nou[i].x]=i;
}
for(i=1;i<=m;i++)
{
f>>x>>y;
g<<lca(x,y)<<'\n';
}
return 0;
}