Pagini recente » Cod sursa (job #408091) | Istoria paginii utilizator/flaviusm | Cod sursa (job #2012326) | Istoria paginii utilizator/ionut_medd | Cod sursa (job #2017119)
#include <fstream>
#include <vector>
#define DIM 100001
using namespace std;
ifstream fi("lca.in");
ofstream fo("lca.out");
int n,m;
int nre,E[2*DIM],L[2*DIM],H[DIM];
int VIZ[DIM];
vector<int> V[DIM];
int M[10*DIM];
void euler(int v,int l)
{
VIZ[v]=1;
nre++;
E[nre]=v,L[nre]=l;
if(!H[v]) H[v]=nre;
for(int i=0;i<V[v].size();i++)
{
int to=V[v][i];
if(!VIZ[to])
{
euler(to,l+1);
nre++;
E[nre]=v,L[nre]=l;
}
}
}
void init(int v,int l,int r)
{
if(l==r)
M[v]=l;
else
{
init(2*v,l,(l+r)/2);
init(2*v+1,(l+r)/2+1,r);
if(L[M[2*v]]<=L[M[2*v+1]])
M[v]=M[2*v];
else
M[v]=M[2*v+1];
}
}
int query(int v,int st,int dr,int l,int r)
{
if(st>r||dr<l)
return -1;
if(st>=l&&dr<=r)
return M[v];
int p1=query(2*v,st,(st+dr)/2,l,r);
int p2=query(2*v+1,(st+dr)/2+1,dr,l,r);
if(p1==-1)
return p2;
if(p2==-1)
return p1;
if(L[p1]<=L[p2])
return p1;
return p2;
}
int main()
{
fi>>n>>m;
for(int i=2;i<=n;i++)
{
int p;
fi>>p;
V[p].push_back(i);
V[i].push_back(p);
}
euler(1,1);
init(1,1,nre);
for(int i=1;i<=m;i++)
{
int a,b;
fi>>a>>b;
fo<<E[query(1,1,nre,min(H[a],H[b]),max(H[a],H[b]))]<<"\n";
}
fi.close();
fo.close();
return 0;
}