Pagini recente » Cod sursa (job #2034542) | Cod sursa (job #279126) | Cod sursa (job #1671984) | Cod sursa (job #1579662) | Cod sursa (job #728784)
Cod sursa(job #728784)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
using namespace std;
#define maxN 100010
#define maxK 21
#define PB push_back
int Level[maxN], tata[maxN], Ap[maxN];
int Euler[maxN << 1], rmq[maxK][maxN << 1];
int Lg[maxN << 1];
vector <int> list[maxN];
void DFS (int nod)
{
Euler[++ Euler[0]] = nod;
Ap[nod] = Euler[0];
for (unsigned int i = 0; i < list[nod].size(); ++ i)
{
int nod2 = list[nod][i];
Level[nod2] = Level[nod] + 1;
DFS (nod2);
Euler[++ Euler[0]] = nod;
}
}
void RMQ ()
{
for (int i = 1; i <= Euler[0]; ++ i) rmq[0][i] = Euler[i];
for (int i = 1; (1 << i) <= Euler[0]; ++ i)
for (int j = 1; j <= Euler[0] - (1 << i) + 1; ++ j)
if (Level[rmq[i - 1][j]] < Level[rmq[i - 1][j + (1 << (i - 1))]]) rmq[i][j] = rmq[i - 1][j];
else rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
}
inline int LCA (int X, int Y)
{
if (X > Y) swap (X, Y);
int nrE = Y - X + 1;
int K = Lg[nrE];
if (Level[rmq[K][X]] < Level[rmq[K][X + nrE - (1 << K)]]) return rmq[K][X];
else return rmq[K][X + nrE - (1 << K)];
}
int main()
{
freopen ("lca.in", "r", stdin);
freopen ("lca.out", "w", stdout);
int N, M;
scanf ("%d %d", &N, &M);
for (int i = 2; i <= N; ++ i)
{
scanf ("%d", &tata[i]);
list[tata[i]].PB (i);
}
DFS (1);
RMQ ();
for (int i = 2; i <= Euler[0]; ++ i) Lg[i] = Lg[i / 2] + 1;
for (int i = 1, X, Y; i <= M; ++ i)
{
scanf ("%d %d", &X, &Y);
printf ("%d\n", LCA (Ap[X], Ap[Y]));
}
return 0;
}