Pagini recente » Cod sursa (job #1992570) | Cod sursa (job #1945819) | Cod sursa (job #328495) | Cod sursa (job #2413619) | Cod sursa (job #2322852)
#include <fstream>
#include <queue>
#include <vector>
using namespace std;
ifstream fi ("lca.in");
ofstream fo ("lca.out");
queue<int> q;
vector<int> v[100005];
int cod[100005],nivel[100005],sir[500005],reprez[100005],loc[100005],mat[100005][20];
int lgsir,nrnod,nrdrum;
void bfs()
{
int codmax=0;
q.push(1);
while (!q.empty())
{
int nod=q.front();
codmax++;cod[nod]=codmax;
q.pop();
for (int i=0;i<v[nod].size();i++)
{
int nextnod=v[nod][i];
q.push(nextnod);
nivel[nextnod]=nivel[nod]+1;
}
}
}
void dfs(int nod)
{
lgsir++;
sir[lgsir]=nod;
for (int i=0;i<v[nod].size();i++)
{
int nextnod=v[nod][i];
dfs(nextnod);
lgsir++;
sir[lgsir]=nod;
}
}
void precalc()
{
for (int i=1;i<=lgsir;i++)
{
mat[i][0]=cod[sir[i]];
if (loc[cod[sir[i]]]==0) loc[cod[sir[i]]]=i;
}
for (int bit=1;(1<<bit)<=lgsir;bit++)
for (int i=1;i+(1<<bit)-1<=lgsir;i++)
mat[i][bit]=min(mat[i][bit-1],mat[i+(1<<(bit-1))][bit-1]);
}
int lca(int codnod1,int codnod2)
{
if (codnod1==codnod2) return codnod1;
int loc1=loc[codnod1],loc2=loc[codnod2];
if (loc2<loc1) swap (loc1,loc2);
int d=loc2-loc1;
int lgmax=0;
while (d>0) {lgmax++;d=d/2;}
lgmax--;
return min(mat[loc1][lgmax],mat[loc2-(1<<lgmax)+1][lgmax]);
}
int main()
{
fi>>nrnod>>nrdrum;
for (int i=2;i<=nrnod;i++)
{
int x;
fi>>x;
v[x].push_back(i);
}
bfs();
dfs(1);
for (int nod=1;nod<=nrnod;nod++)
reprez[cod[nod]]=nod;
precalc();
for (int i=1;i<=nrdrum;i++)
{
int x,y;
fi>>x>>y;
int sol=reprez[lca(cod[x],cod[y])];
fo<<sol<<'\n';
}
return 0;
}