Pagini recente » Cod sursa (job #1194570) | Cod sursa (job #422750) | Cod sursa (job #79705) | Cod sursa (job #2534918) | Cod sursa (job #2906757)
#include <fstream>
using namespace std;
const int N = 1e5;
const int L = 17;
int t[L][N], nivel[N+1], log[N+1], n;
void calcul_t()
{
for (int e = 1; e < L; e++)
{
for (int i = 1; i <= n; i++)
{
t[e][i] = t[e-1][t[e-1][i]];///stramsoul de ordin 2^e=stramosul de ord 2^(e-1) al
///stramosului de ordinul 2^(e-1)
}
}
}
void nivelul(int x)
{
if (nivel[x] != 0)
{
return;
}
nivelul(t[0][x]);
nivel[x] = 1 + nivel[t[0][x]];
}
void calcul_nivel()
{
nivel[1] = 1;
for (int i = 2; i <= n; i++)
{
nivelul(i);
}
}
void calcul_log()
{
log[1] = 0;
for (int i = 2; i <= n; i++)
{
log[i] = 1 + log[i/2];
}
}
int stramos(int x, int ord)
{
///returneaza stramosul de ordinul ord al lui x
int e = 0;
while (ord != 0)
{
if (ord % 2 != 0)
{
x = t[e][x];
}
e++;
ord /= 2;
}
return x;
}
int lca(int x, int y)
{
int e = log[nivel[x]];
while (e >= 0)
{
if (t[e][x] != t[e][y])
{
x = t[e][x];
y = t[e][y];
}
e--;
}
return t[0][x];///stiu ca t[0][x] = t[0][y]
}
int main()
{
ifstream in("lca.in");
ofstream out("lca.out");
int nq;
in >> n >> nq;
for (int i = 2; i <= n; i++)
{
in >> t[0][i];
}
calcul_t();
calcul_nivel();
calcul_log();
for (int i = 0; i < nq; i++)
{
int x, y;
in >> x >> y;
if (nivel[x] > nivel[y])
{
swap(x, y);
}
y = stramos(y, nivel[x] - nivel[y]);
if (y == x)
{
out << x << "\n";
}
else
{
out << lca(x, y) << "\n";
}
}
return 0;
}