Pagini recente » Cod sursa (job #2073612) | Cod sursa (job #2130813) | Cod sursa (job #1573920) | Cod sursa (job #1521656) | Cod sursa (job #2651059)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int N = 1e5 + 5, MAXLOG = 18;
vector<int> g[N];
int rmq[2 * N][MAXLOG], SirEuler[2 * N], lvl[N], pos[N], Log2[2 * N];
void df(int nod, int nivel)
{
lvl[nod] = nivel;
SirEuler[++SirEuler[0]] = nod;
pos[nod] = SirEuler[0];
for (int neigh : g[nod])
{
df(neigh, nivel + 1);
SirEuler[++SirEuler[0]] = nod;
}
}
int GetMin(int x, int y)
{
if (lvl[x] < lvl[y])
{
return x;
}
return y;
}
void precompute()
{
// Sirul Euler
df(1, 0);
Log2[1] = 0;
for (int i = 2; i <= SirEuler[0]; i++)
{
Log2[i] = Log2[i / 2] + 1;
}
for (int i = 1; i <= SirEuler[0]; i++)
{
rmq[i][0] = SirEuler[i];
}
for (int p = 1; (1 << p) <= SirEuler[0]; p++)
{
for (int i = 1; i + (1 << p) <= SirEuler[0]; i++)
{
rmq[i][p] = GetMin(rmq[i][p - 1], rmq[i + (1 << (p - 1))][p - 1]);
}
}
}
int SolveQuery(int x, int y)
{
int px = pos[x];
int py = pos[y];
if (px > py)
{
swap(px, py);
}
int dif = py - px + 1;
int level = Log2[dif];
return GetMin(rmq[px][level], rmq[py - (1 << level) + 1][level]);
}
int main()
{
int n, m;
fin >> n >> m;
for (int i = 2; i <= n; i++)
{
int t;
fin >> t;
g[t].push_back(i);
}
precompute();
while (m--)
{
int x, y;
fin >> x >> y;
fout << SolveQuery(x, y) << '\n';
}
}