Pagini recente » Cod sursa (job #624010) | Cod sursa (job #1519499) | Monitorul de evaluare | Cod sursa (job #1431240) | Cod sursa (job #582155)
Cod sursa(job #582155)
#include <fstream>
using namespace std;
int n,m,i,rmq[20][400010],h[200010],l[200010],first[100001],x;
struct nod{int y; nod *next;};
int lg[200010];
nod *G[100001];
int add(int a,int b)
{
nod *nou=new nod;
nou->y=b;
nou->next=G[a];
G[a]=nou;
return 0;
}
int dfs(int n,int lev)
{
h[++h[0]]=n;
l[h[0]]=lev;
first[n]=h[0];
nod *it=new nod;
it=G[n];
while (it)
{
dfs(it->y,lev+1);
h[++h[0]]=n;
l[h[0]]=lev;
it=it->next;
}
}
int Rmq()
{
for (i=2;i<=h[0];i++)
lg[i]=lg[i/2]+1;
for (i=1;i<=h[0];i++)
rmq[0][i]=i;
int j,lo;
for (i=1;(1<<i)<h[0];i++)
{
lo=(1<<(i-1));
for (j=1;j+2*lo<=h[0];j++)
{
rmq[i][j]=rmq[i-1][j];
if (l[rmq[i][j]]>l[rmq[i-1][j+lo]])
rmq[i][j]=rmq[i-1][j+lo];
}
}
return 0;
}
int LCA(int x,int y)
{
int a,b,aux,lo,diff,sh,sol;
a=first[x];
b=first[y];
if (a>b) {aux=a; a=b; b=aux;}
diff=b-a+1;
lo=lg[diff];
sh=diff-(1<<lo);
sol=rmq[lo][a];
if (l[sol]>l[rmq[lo][a+sh]])
sol=rmq[lo][a+sh];
return h[sol];
}
int main(void)
{
ifstream fin("lca.in");
ofstream fout("lca.out");
fin>>n>>m;
for (i=2;i<=n;i++)
{
fin>>x;
add(x,i);
}
dfs(1,0);
Rmq();
int a,b;
for (i=1;i<=m;i++)
{
fin>>a>>b;
fout<<LCA(a,b)<<"\n";
}
return 0;
}