Pagini recente » Cod sursa (job #1390288) | Cod sursa (job #2244870) | Cod sursa (job #3041321) | Cod sursa (job #1989078) | Cod sursa (job #2833495)
#include <bits/stdc++.h>
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
vector <int> h[100005];
int n, e[200005], niv[200005], lg[25], k , poz[200005], p , m;
int rmq[21][200005];
/**
e- retine nodurile in ordinea parcurgerii Euler
niv[i] = nivelul pe care se alfa nodul e[i]
poz[i] = o pozitie unde se gaseste nodul i in e[]
*/
void Euler (int k, int nivel)
{
e[++p] = k;
niv[p] = nivel;
poz[k] = p;
for (int i : h[k])
{
Euler(i, nivel + 1);
e[++p] = k;
niv[p] = nivel;
}
}
void MakeRMQ ()
{
lg[1] = 0;
for (int i = 2; i <= p; i++)
lg[i] = lg[i / 2] + 1;
for(int i = 1; i <= p; i++)
rmq[0][i] = i; /// e[i] este minim si se afla la poz i
for (int i = 1; (1 << i) <= p; i++)
for (int j = 1; j <= p - (1 << i) + 1; j++)
{
int len = (1 << (i - 1));
rmq[i][j] = rmq[i - 1][j];
if (niv[rmq[i - 1][j]] > niv[rmq[i - 1][j + len]])
rmq[i][j] = rmq[i - 1][j + len];
}
}
int main()
{
fin >> n >> m;
for (int i = 2; i <= n; i++)
{
int j;
fin >> j;
h[j].push_back(i);
}
Euler(1, 1);
MakeRMQ();
/// Interogari
while (m--)
{
int x , y;
fin >> x >> y;
x = poz[x];
y = poz[y];
if (x > y)
swap(x , y);
int expo = lg[y - x + 1];
int len = (1 << expo);
int lca1 = rmq[expo][x];
int lca2 = rmq[expo][y - len + 1];
if (niv[lca1] > niv[lca2])
fout << e[lca2] << "\n";
else fout << e[lca1] << "\n";
}
return 0;
}