Pagini recente » Cod sursa (job #3348026) | Cod sursa (job #175929) | Cod sursa (job #3308758) | Cod sursa (job #2822772) | Cod sursa (job #3308780)
//euler+aint
#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], aint[4 * 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 (int nod, int st, int dr)
{
if (st == dr)
{
aint[nod] = st;
return;
}
int mij = (st + dr) / 2;
init (2 * nod, st, mij);
init (2 * nod + 1, mij + 1, dr);
aint[nod] = aint[2 * nod];
if (lvl[aint[2 * nod]] > lvl[aint[2 * nod + 1]])
aint[nod] = aint[2 * nod + 1];
}
int query (int nod, int st, int dr, int p, int q)
{
if (p <= st && dr <= q)
return aint[nod];
int cl = 0, cr = 0;
int mij = (st + dr) / 2;
if (p <= mij)
cl = query (2 * nod, st, mij, p, q);
if (mij + 1 <= q)
cr = query (2 * nod + 1, mij + 1, dr, p, q);
int sol = -1;
if (cl != 0)
sol = cl;
if (cr != 0)
{
if (sol == -1 || lvl[cr] < lvl[sol])
sol = cr;
}
return sol;
}
int lca (int x, int y)
{
x = poz[x];
y = poz[y];
if (x > y)
swap (x, y);
return euler[query (1, 1, k, 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 (1, 1, k);
for (int i = 1; i <= m; i++)
{
int x, y;
fin >> x >> y;
fout << lca (x, y) << '\n';
}
return 0;
}