Pagini recente » Cod sursa (job #1368891) | Cod sursa (job #2285926) | Monitorul de evaluare | Cod sursa (job #1310555) | Cod sursa (job #2271848)
#include <bits/stdc++.h>
using namespace std;
const int NMAX=1e6+5;
vector <int> G[NMAX];
int N, M, i, X, u, v, cnt=0;
int RMQ[31][2*NMAX];
int position[NMAX];
bool pus[NMAX];
struct Euler
{
int Nod, Nivel;
};
Euler A[NMAX];
int log2 (int N)
{
int p2=1;
int exp=0;
while(p2<N)
{
p2*=2;
exp++;
}
if(p2>N)
exp--;
return exp;
}
void DFS (int Nod, int Nivel)
{
pus[Nod]=true;
A[++cnt].Nod=Nod;
A[cnt].Nivel=Nivel;
position[Nod]=cnt;
for(int i=0; i<G[Nod].size(); i++)
if(pus[G[Nod][i]]==false)
{
pus[G[Nod][i]]=true;
DFS(G[Nod][i], Nivel+1);
A[++cnt].Nod=Nod;
A[cnt].Nivel=Nivel;
}
}
void precalculation ()
{
int M=2*N-1;
for(int i=1; i<=M; i++)
RMQ[0][i]=i;
for(int i=1; i<=log2(M); i++)
for(int j=1; j<=(M-(1<<i)+1); j++)
{
if(A[RMQ[i-1][j+(1<<(i-1))]].Nivel < A[RMQ[i-1][j]].Nivel)
RMQ[i][j]=RMQ[i-1][j+(1<<(i-1))];
else RMQ[i][j]=RMQ[i-1][j];
}
}
int Query (int u, int v)
{
int i=position[u];
int j=position[v];
if(i==j)
return A[i].Nod;
else
{
if(i>j)
swap(i, j);
int K=0;
K=log2(j-i+1);
if(A[RMQ[K][i]].Nivel < A[RMQ[K][j-(1<<K)+1]].Nivel)
return A[RMQ[K][i]].Nod;
else return A[RMQ[K][j-(1<<K)+1]].Nod;
}
}
int main()
{
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
scanf("%d%d", &N, &M);
for(i=2; i<=N; i++)
{
scanf("%d", &X);
G[X].push_back(i);
}
DFS(1, 1);
precalculation();
for(i=1; i<=M; i++)
{
scanf("%d%d", &u, &v);
printf("%d\n", Query(u, v));
}
return 0;
}