Pagini recente » Cod sursa (job #710692) | Cod sursa (job #2194999) | Autentificare | Cod sursa (job #973511) | Cod sursa (job #3185822)
#include <bits/stdc++.h>
#define SIZE 1005
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int n,m,nivel[SIZE],poz[SIZE],e[2*SIZE],p[2*SIZE],t[SIZE],k;
vector<int>a[SIZE];
struct elem
{
int nod,lvl;
}v[2*SIZE],rmq[20][2*SIZE];
void dfs(int nod)
{
nivel[nod]=nivel[t[nod]]+1;
v[++k].nod=nod;
v[k].lvl=nivel[nod];
for(auto u:a[nod])
{
dfs(u);
v[++k].nod=nod;
v[k].lvl=nivel[nod];
}
}
void precalculare()
{
int x,y=1;
for(int i=1;i<=k;i++)rmq[0][i]=v[i];
for(x=1;x*2<=k;x*=2)
{
for(int i=1;i<=k-2*x+1;i++)
if(rmq[y-1][i].lvl<rmq[y-1][i+x].lvl)rmq[y][i]=rmq[y-1][i];
else rmq[y][i]=rmq[y-1][i+x];
y++;
}
}
void rmqlca()
{
precalculare();
int x=1,y=0,i;
for(i=1;i<=k;i++)
{
if(x*2<=i)x*=2,y++;
p[i]=x;
e[i]=y;
}
}
int lca(int x,int y)
{
x=poz[x];
y=poz[y];
if(x>y)swap(x,y);
int aa=e[y-x+1],bb=p[y-x+1];
if(rmq[aa][x].lvl<rmq[aa][y-bb+1].lvl)return rmq[aa][x].nod;
else return rmq[aa][y-bb+1].nod;
}
int main()
{
int i,x,y;
f>>n>>m;
for(i=2;i<=n;i++)
{
f>>t[i];
a[t[i]].push_back(i);
}
dfs(1);
rmqlca();
//prima aparitie a fiecarui nod in reprezentarea Euler
for(i=1;i<=k;i++)
if(poz[v[i].nod]==0)poz[v[i].nod]=i;
for(i=1;i<=m;i++)
{
f>>x>>y;
g<<lca(x,y)<<'\n';
}
return 0;
}