Pagini recente » Cod sursa (job #1353881) | Cod sursa (job #2486863) | Cod sursa (job #2569775) | Cod sursa (job #2901901) | Cod sursa (job #2660301)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, m, cnt, T[100001], E[200001], I[100001], Log2[200001];
vector<int> G[100001], Mi[22];
void Euler(int x)
{
E[++cnt] = x;
I[x] = cnt;
for (int y : G[x])
{
if (y == T[x])
continue;
Euler(y);
E[++cnt] = x;
}
}
void Prep()
{
// Construiesc arborele.
for (int i = 2; i <= n; ++i)
{
G[i].push_back(T[i]);
G[T[i]].push_back(i);
}
// Turul Euler.
Euler(1);
// Construiesc Log2 (Log2[x] = [ln(x) / ln(2)]).
for (int i = 2; i <= 200000; ++i)
Log2[i] = Log2[i / 2] + 1;
// Construiesc Mi pentru Rmq.
Mi[0] = vector<int>(cnt + 1);
for (int i = 1; i <= cnt; ++i)
Mi[0][i] = E[i];
for (int e = 1; e <= Log2[cnt]; ++e)
{
Mi[e] = vector<int>(cnt - (1 << e) + 2);
for (int i = 1; i <= cnt - (1 << e) + 1; ++i)
Mi[e][i] = min(Mi[e - 1][i], Mi[e - 1][i + (1 << (e - 1))]);
}
}
int Rmq(int a, int b)
{
int e = Log2[b - a + 1];
return min(Mi[e][a], Mi[e][b - (1 << e) + 1]);
}
int main()
{
fin >> n >> m;
for (int i = 1; i < n; ++i)
fin >> T[i + 1];
Prep();
for (int i = 1; i <= m; ++i)
{
int x, y;
fin >> x >> y;
fout << Rmq(min(I[x], I[y]), max(I[x], I[y])) << '\n';
}
return 0;
}