Pagini recente » Cod sursa (job #1808934) | Cod sursa (job #3120506) | Cod sursa (job #833919) | Cod sursa (job #310641) | Cod sursa (job #2789551)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector <int> V[100005];
int nivel[100005], euler[100005], poz[100005], lll[100005], rmq[20][100005];
int n, m, cnt;
void Citire()
{
int x, i;
fin >> n >> m;
for(i = 2;i <= n;i++)
{
fin >> x;
V[x].push_back(i);
}
nivel[1] = 0;
}
void DFS(int nod)
{
euler[++cnt] = nod;
poz[nod] = cnt;
for(auto x : V[nod])
{
nivel[x] = nivel[nod] + 1;
DFS(x);
euler[++cnt] = nod;
}
}
void RMQ()
{
int i, j;
lll[1] = 0;
for(i = 2;i <= cnt;i++)
lll[i] = lll[i / 2] + 1;
for(i = 1;i <= cnt;i++)
rmq[0][i] = i;
int P = lll[cnt];
for(i = 1;i <= P;i++)
for(j = 1;j <= cnt - (1 << i) + 1;j++)
{
rmq[i][j] = rmq[i - 1][j];
if(nivel[euler[rmq[i - 1][j]]] > nivel[euler[rmq[i - 1][j + (1 << (i - 1))]]])
rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
}
}
int Query(int x, int y)
{
int length = y - x + 1;
int pp = lll[length], ansnod;
ansnod = rmq[pp][x];
if(nivel[euler[ansnod]] > nivel[euler[rmq[y + 1 - (1 << pp)][pp]]])
ansnod = rmq[pp][y + 1 - (1 << pp)];
return euler[ansnod];
}
int main()
{
Citire();
DFS(1);
RMQ();
while(m--)
{
int x, y;
fin >> x >> y;
int p1 = min(poz[x], poz[y]);
int p2 = max(poz[x], poz[y]);
fout << Query(p1, p2) << "\n";
}
return 0;
}