Pagini recente » Cod sursa (job #2292864) | Cod sursa (job #792025) | Cod sursa (job #2372506) | Cod sursa (job #1238936) | Cod sursa (job #2353094)
#include <bits/stdc++.h>
#define MAXLOG 20
#define MAXN 100005
int Log2[MAXN];
void Precompute() {
Log2[1] = 0;
for (int i=2; i<MAXN; ++i)
Log2[i] = Log2[i>>1] + 1;
}
int N, M, Parent[MAXN];
std::vector <int> Sons[MAXN];
inline void AddEdge(int X, int Y) {
Sons[X].push_back(Y);
Parent[Y] = X;
}
int EulerSize, Euler[4*MAXN], LVL[MAXN], Depth[MAXN],
Euidx[MAXN];
void Liniarizare(int Vertex = 1) {
LVL[Vertex] = LVL[Parent[Vertex]] + 1;
Euler[++EulerSize] = Vertex;
Euidx[Vertex] = EulerSize;
Depth[EulerSize] = LVL[Vertex];
for (auto Son:Sons[Vertex])
if (!LVL[Son]) {
Liniarizare(Son);
Euler[++EulerSize] = Vertex;
Depth[EulerSize] = LVL[Vertex];
}
}
int RMQ[20][MAXN];
void BuildRMQ() {
for (int i=1; i<=EulerSize; ++i)
RMQ[0][i] = i;
for (int lg=1, i; (1<<lg) <= EulerSize; ++lg)
for (i=1; i + (1<<lg)-1 <= EulerSize; ++i) {
if (Depth[RMQ[lg-1][i]] < Depth[RMQ[lg-1][i + (1<<(lg-1))]])
RMQ[lg][i] = RMQ[lg-1][i];
else
RMQ[lg][i] = RMQ[lg-1][i + (1<<(lg-1))];
}
}
int LCA(int X, int Y) {
X = Euidx[X];
Y = Euidx[Y];
if (X > Y) std::swap(X, Y);
int len = (Y-X+1);
len = Log2[len];
int A = RMQ[len][X], B = RMQ[len][Y - (1<<len)+1];
if (Depth[A] < Depth[B])
return Euler[A];
return Euler[B];
}
std::ifstream In ("lca.in");
std::ofstream Out("lca.out");
void Citire() {
In >> N >> M;
for (int i=2, P; i<=N; ++i)
In >> P, AddEdge(P, i);
}
void Rezolvare() {
Liniarizare();
BuildRMQ();
int X, Y;
while (M--)
In >> X >> Y,
Out << LCA(X, Y) << '\n';
}
int main()
{
Citire();
Precompute();
Rezolvare();
return 0;
}