Pagini recente » Cod sursa (job #879339) | Cod sursa (job #1205073) | Cod sursa (job #1391026) | Cod sursa (job #2423657) | Cod sursa (job #3276398)
#include <fstream>
#include <vector>
#include <iostream>
#include <algorithm>
#include <set>
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
const int N = 1e5 + 2;
vector <int> L[N], euler, level, pos;
int n, q, rmq[18][2 * N], exp[2 * N];
void EulerTour(int nod, int currlevel)
{
euler.push_back(nod);
level.push_back(currlevel);
if (!pos[nod]) pos[nod] = euler.size() - 1;
for (auto next : L[nod])
{
EulerTour(next, currlevel + 1);
euler.push_back(nod);
level.push_back(currlevel);
}
}
void Build_RMQ()
{
exp[1] = 0;
for (int i = 2; i < euler.size(); i++)
exp[i] = exp[i / 2] + 1;
for (int i = 1; i < euler.size(); i++)
rmq[0][i] = i;
for (int i = 1; i <= exp[euler.size() - 1]; i++)
for (int j = 1; j <= euler.size() - (1 << i); 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))];
}
int Query (int a, int b)
{
int x = pos[a];
int y = pos[b];
if (x > y) swap(x, y);
int k = exp[y - x + 1];
if (level[rmq[k][x]] < level[rmq[k][y - (1 << k) + 1]])
return euler[rmq[k][x]];
return euler[rmq[k][y - (1 << k) + 1]];
}
void Read()
{
fin >> n >> q;
for (int i = 2; i <= n; i++)
{
int x;
fin >> x;
L[x].push_back(i);
}
pos.resize(n + 1, 0);
euler.push_back(2e9);
level.push_back(2e9);
EulerTour(1, 1);
Build_RMQ();
}
void Solve()
{
for (int i = 1; i <= q; i++)
{
int x, y;
fin >> x >> y;
fout << Query(x, y) << '\n';
}
}
int main()
{
Read();
Solve();
return 0;
}