Pagini recente » Cod sursa (job #2623442) | Cod sursa (job #2684810) | Istoria paginii runda/drumarb2 | Cod sursa (job #1435812) | Cod sursa (job #2340780)
#include <bits/stdc++.h>
std::istream& operator >> (std::istream& stream, std::pair <int, int>& data) {
return stream >> data.first >> data.second;
}
#define int_pair std::pair <int, int>
#define MAXN 200005
#define MAXLOG 20
int Log2[MAXN];
void Precompute() {
Log2[1] = 0;
for (int i=2; i<MAXN; ++i)
Log2[i] = Log2[i>>1] + 1;
}
int N, K;
std::vector <int> ADC[MAXN];
inline void AddEdge(int X, int Y) {
ADC[X].push_back(Y);
ADC[Y].push_back(X);
}
int NEuler, Euler[MAXN], LVL[MAXN],
Euleridx[MAXN], H[MAXN];
void Liniarizare(int Vertex = 1, int Height = 1, int Parent = 0) {
Euler[++NEuler] = Vertex;
LVL[NEuler] = Height;
Euleridx[Vertex] = NEuler;
H[Vertex] = Height;
for (auto Edge:ADC[Vertex]) {
if (Edge == Parent) continue;
Liniarizare(Edge, Height+1, Vertex);
Euler[++NEuler] = Vertex;
LVL[NEuler] = Height;
}
}
int RMQ[20][MAXN];
void BuildRMQ() {
for (int i=1; i<=NEuler; ++i)
RMQ[0][i] = i;
for (int i=1, j; (1<<i)<NEuler; ++i)
for (j=1; j <= NEuler-(1<<i)+1; ++j)
if (LVL[RMQ[i-1][j]] < LVL[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))];
}
int LCA(int X, int Y) {
X = Euleridx[X];
Y = Euleridx[Y];
if (X > Y) std::swap(X, Y);
int Lg = Log2[Y-X+1];
int A = RMQ[Lg][X], B = RMQ[Lg][Y - (1<<Lg)+1];
if (LVL[A] < LVL[B])
return Euler[A];
return Euler[B];
}
std::ifstream In("lca.in");
std::ofstream Out("lca.out");
int_pair Terror[MAXN];
std::vector <int_pair> CT;
bool cmp(const int_pair& p0, const int_pair& p1) {
return H[p0.first] > H[p1.first];
}
bool Seen[MAXN];
bool DFS(int Vertex) {
Seen[Vertex] = 1;
for (auto Edge:ADC[Vertex])
if (!Seen[Edge] && H[Edge] > H[Vertex])
DFS(Edge);
}
void Citire() {
for (int i=1; i<=N; ++i)
ADC[i].clear();
In >> N >> K;
for (int i=2, X, Y; i<=N; ++i)
In >> X, AddEdge(X, i);
}
void Rezolvare() {
Liniarizare();
BuildRMQ();
for (int i=1, X, Y; i<=K; ++i)
In >> X >> Y, Out << LCA(X, Y) << '\n';
}
int main()
{
Precompute();
int T;
T = 1;
while (T--) {
Citire();
Rezolvare();
}
return 0;
}