Pagini recente » Cod sursa (job #307649) | Cod sursa (job #2130439) | Cod sursa (job #941511) | Cod sursa (job #2126704) | Cod sursa (job #1168687)
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int NMAX = 100000+5;
const int LMAX = 18;
void Read(),Precompute(),Solve();
int N,M,Cnt;
int Father[NMAX];
vector<int> Graph[NMAX];
int RMQ[LMAX][2*NMAX];
int Euler[2*NMAX];
int First[NMAX];
int Depth[NMAX];
void DFS(int node,int depth)
{
vector<int>::iterator it;
Depth[node] = depth;
Euler[++Cnt] = node;
First[node] = Cnt;
for(it = Graph[node].begin(); it != Graph[node].end(); it++)
if(!Depth[*it])
{
DFS(*it,depth+1);
Euler[++Cnt] = node;
}
}
void Build_RMQ()
{
int i,p,step;
for(i = 1; i <= Cnt; i++)
RMQ[0][i] = i;
for(step = 1, p = 2; p <= Cnt; step++, p <<= 1)
for(i = 1; i + p <= Cnt; i++)
if(Depth[Euler[RMQ[step-1][i]]] <= Depth[Euler[RMQ[step-1][i + (p>>1)]]]) RMQ[step][i] = RMQ[step-1][i];
else RMQ[step][i] = RMQ[step-1][i + (p>>1)];
}
int Query(int x,int y)
{
int dist = y - x + 1,step,p;
for(step = 0, p = 1; p <= dist; step++, p <<= 1);
step--;
p >>= 1;
if(Depth[Euler[RMQ[step][x]]] <= Depth[Euler[RMQ[step][y-p+1]]]) return Euler[RMQ[step][x]];
else return Euler[RMQ[step][y-p+1]];
}
int main()
{
Read();
Precompute();
Solve();
return 0;
}
void Read()
{
int i;
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
scanf("%d%d",&N,&M);
for(i = 2; i <= N; i++)
{
scanf("%d",&Father[i]);
Graph[Father[i]].push_back(i);
}
}
void Precompute()
{
DFS(1,1);
Build_RMQ();
}
void Solve()
{
int x,y;
for(; M; --M)
{
scanf("%d%d",&x,&y);
x = First[x];
y = First[y];
if(x>y) swap(x,y);
printf("%d\n",Query(x,y));
}
}