Pagini recente » Cod sursa (job #3038537) | Cod sursa (job #3150799) | Cod sursa (job #121064) | Cod sursa (job #865210) | Cod sursa (job #2387129)
#include <fstream>
#include <vector>
using namespace std;
ifstream fi ("lca.in");
ofstream fo ("lca.out");
vector<int> v[100005];
int nrnod,nrq,lg,eul[200006],nivel[100006],firstap[100006],rmq[20][200006];
void dfs(int nod,int lvl)
{
nivel[nod]=lvl;
for (int i=0;i<v[nod].size();i++)
{
int nextnod=v[nod][i];
lg++;
eul[lg]=nod;
dfs(nextnod,lvl+1);
}
lg++;
eul[lg]=nod;
}
void precalc()
{
for (int i=1;i<=lg;i++) rmq[0][i]=eul[i];
for (int lvl=1;(1<<lvl)<=lg;lvl++)
for (int i=1;i+(1<<lvl)-1<=lg;i++)
{
int nod1=rmq[lvl-1][i];
int nod2=rmq[lvl-1][i+(1<<(lvl-1))];
if (nivel[nod1]<=nivel[nod2]) rmq[lvl][i]=nod1;
else rmq[lvl][i]=nod2;
}
}
int querry(int nod1,int nod2)
{
int power=0,poz1,poz2;
poz1=firstap[nod1];
poz2=firstap[nod2];
if (poz1>poz2) swap (poz1,poz2);
int dif=poz2-poz1+1;
while (dif) {dif=dif/2;power++;}
power--;
nod1=rmq[power][poz1];
nod2=rmq[power][poz2-(1<<power)+1];
if (nivel[nod1]<nivel[nod2]) return nod1;
else return nod2;
}
int main()
{
fi>>nrnod>>nrq;
for (int x=2;x<=nrnod;x++)
{
int y;
fi>>y;
v[y].push_back(x);
}
dfs(1,0);
for (int i=1;i<=lg;i++)
if (firstap[eul[i]]==0) firstap[eul[i]]=i;
// for (int i=1;i<=lg;i++) fo<<eul[i]<<' ';
precalc();
for (int i=1;i<=nrq;i++)
{
int x,y;
fi>>x>>y;
fo<<querry(x,y)<<'\n';
}
return 0;
}