Pagini recente » Cod sursa (job #99167) | Cod sursa (job #2505817) | Cod sursa (job #2862496) | Cod sursa (job #1551977) | Cod sursa (job #2325509)
#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,fr[2*nmax];
// 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]=x;
if (fr[x]==0) fr[x]=k;
etour(x);
}
et[++k]=fa[node];
}
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]=fr[1]=1;
etour(1);
constr(2*n-1);
for (int i=1;i<=m;i++)
{
f>>a>>b;
if (a==b)
{
g<<a<<'\n';
continue;
}
g<<RMQ(min(fr[a],fr[b]),max(fr[a],fr[b]))<<'\n';
}
f.close();
g.close();
return 0;
}