Pagini recente » Cod sursa (job #1106568) | Cod sursa (job #2085122) | Cod sursa (job #3124386) | Cod sursa (job #251897) | Cod sursa (job #3308773)
//euler+rmq
#include <bits/stdc++.h>
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
const int nmax = 2e5 + 5;
vector <int> g[nmax];
int n, m, k, euler[nmax], lvl[nmax], poz[nmax], lg[nmax], rmq[20][nmax];
void build (int nod, int h)
{
euler[++k] = nod;
lvl[k] = h;
poz[nod] = k;
for (auto it : g[nod])
{
build (it, h + 1);
euler[++k] = nod;
lvl[k] = h;
}
}
void init ()
{
for (int i = 2; i <= k; i++)
lg[i] = lg[i / 2] + 1;
for (int i = 1; i <= k; i++)
rmq[0][i] = i;
for (int i = 1; i <= lg[k]; i++)
{
for (int j = 1; j <= k - (1 << i) + 1; j++)
{
int l = 1 << (i - 1);
rmq[i][j] = rmq[i - 1][j];
if (lvl[rmq[i - 1][j + l]] < lvl[rmq[i][j]]) rmq[i][j] = rmq[i - 1][j + l];
}
}
}
int query (int x, int y)
{
int k = lg[y - x];
int sol = rmq[k][x];
if (lvl[rmq[k][y - (1 << k) + 1]] < lvl[sol])
sol = rmq[k][y - (1 << k) + 1];
return sol;
}
int lca (int x, int y)
{
x = poz[x];
y = poz[y];
if (x > y)
swap (x, y);
return euler[query (x, y)];
}
int main ()
{
fin >> n >> m;
for (int i = 2; i <= n; i++)
{
int x;
fin >> x;
g[x].push_back (i);
}
build (1, 1);
init ();
for (int i = 1; i <= m; i++)
{
int x, y;
fin >> x >> y;
fout << lca (x, y) << '\n';
}
return 0;
}