Pagini recente » Cod sursa (job #646298) | Cod sursa (job #2469939) | Cod sursa (job #992877) | Cod sursa (job #170646) | Cod sursa (job #3328417)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int NMAX=1e5,PMAX=18;
int n,i,q,x,y,nr,start[NMAX+5],E[2*NMAX+5],depth[NMAX+5];
bool viz[NMAX+5];
vector <int> adj[NMAX+5];
struct RMQ{
int node,depth;}r[PMAX+5][2*NMAX+5];
void dfs(int node)
{
viz[node]=1;
nr++;
r[0][nr].node=node;
r[0][nr].depth=depth[node];
start[node]=nr;
for (auto node2: adj[node])
if (!viz[node2])
{
depth[node2]=depth[node]+1;
dfs(node2);
nr++;
r[0][nr].node=node;
r[0][nr].depth=depth[node];
}
}
void precalc()
{
for (i=2; i<=nr; i++)
E[i]=E[i>>1]+1;
int p;
for (p=1; (1<<p)<=nr; p++)
{
for (i=1; i<=nr; i++)
{
r[p][i]=r[p-1][i];
if (i+(1<<(p-1))<=nr)
{
if (r[p-1][i+(1<<(p-1))].depth<r[p][i].depth)
r[p][i]=r[p-1][i+(1<<(p-1))];
}
}
}
}
int lca(int x, int y)
{
int st=start[x],dr=start[y];
if (st>dr)
swap(st,dr);
int len=dr-st+1,e=E[len];
RMQ Eda=r[e][st],Edase=r[e][dr-(1<<e)+1];
if (Eda.depth<Edase.depth)
return Eda.node;
else
return Edase.node;
}
int main()
{
ios_base::sync_with_stdio(false);
fin.tie(nullptr);
fin>>n>>q;
for (i=2; i<=n; i++)
{
fin>>x;
adj[x].push_back(i);
adj[i].push_back(x);
}
dfs(1);
precalc();
while (q--)
{
fin>>x>>y;
fout<<lca(x,y)<<'\n';
}
return 0;
}