Pagini recente » Cod sursa (job #1549947) | Cod sursa (job #423126) | Cod sursa (job #3161386) | Cod sursa (job #505085) | Cod sursa (job #2325480)
#include <fstream>
#include <queue>
#define nmax 100004
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int n,m,fa[nmax],a,b,en[nmax],et[2*nmax],k=1,posa,posb,rmq[2*nmax][20],lg[2*nmax],dim;
// en[i]=corespondentul nodului initial i, pentru par.eu.
queue <int> q;
vector <int> G[nmax];
void bfs (void)
{
int k=2;
en[1]=1;
q.push(1);
while (!q.empty())
{
int node=q.front();
q.pop();
for (auto ne:G[node])
{
if (!en[ne])
{
en[ne]=k++;
q.push(ne);
}
}
}
}
void etour (int node)
{
while (!G[node].empty())
{
int x=G[node].back();
G[node].pop_back();
et[++k]=en[x];
etour(x);
}
et[++k]=en[fa[node]];
}
int getpos (int x)
{
for (int i=1;i<=2*n-1;i++)
if (et[i]==x) return i;
}
void constr (int dim)
{
for (int i=1;i<=dim;i++) rmq[i][0]=et[i];
for (int j=1;(1<<j)<=dim;j++)
for (int i=1;i+(1<<j)-1<=dim;i++)
rmq[i][j]=min(rmq[i][j-1],rmq[i+(1<<(j-1))][j-1]);
lg[1]=0;
for (int i=2;i<=dim;i++) lg[i]=lg[i/2]+1;
}
int RMQ (int x,int y)
{
return min(rmq[x][lg[y-x+1]],rmq[y-(1<<lg[y-x+1])+1][lg[y-x+1]]);
}
int main()
{
f>>n>>m;
fa[1]=1;
for (int i=2;i<=n;i++)
{
f>>fa[i];
G[fa[i]].push_back(i);
}
bfs();
et[1]=1;
etour(1);
constr(2*n);
for (int i=1;i<=m;i++)
{
f>>a>>b;
posa=getpos(en[a]);
posb=getpos(en[b]);
g<<RMQ(min(posa,posb),max(posa,posb))<<'\n';
}
f.close();
g.close();
return 0;
}