Pagini recente » Cod sursa (job #1937609) | Cod sursa (job #207165) | Cod sursa (job #1749869) | Cod sursa (job #2348838) | Cod sursa (job #2833488)
#include <bits/stdc++.h>
#define nmax 200004
using namespace std;
int E[nmax], k; /// nodurile din parcurgerea Euler
int niv[nmax]; /// nivelele nodurilor din parcurgerea Euler
int P[nmax / 2]; /// P[i] = o pozitie a nodului i in E[]
int rmq[20][nmax]; /// range minimum query
vector <int> L[nmax / 2]; /// listele de adiacenta
int len[nmax];
int n;
void DFS(int nod, int nivel)
{
E[++k] = nod;
niv[k] = nivel;
P[nod] = k;
for(auto i : L[nod])
{
DFS(i, nivel + 1);
E[++k] = nod;
niv[k] = nivel;
}
}
int main()
{
int i, j, Q, x, y, p, sol;
/// citirea arborelui
ifstream fin("lca.in");
ofstream fout("lca.out");
fin >> n >> Q;
for (i = 2; i <= n; i++)
{
fin >> x;
L[x].push_back(i);
}
/// Construiesc E[] si niv[]
DFS(1, 0); /// radacina este 1, pe nivelul 0
/// RMQ
len[1] = 0;
for (i = 2; i <= k; ++i)
len[i] = 1 + len[i / 2];
/// rmq[i][j] = pozitia minimului de pe intervalul [j..j+2^i-1]
for (i = 1; i <= k; ++i)
rmq[0][i] = i;
for (i = 1; (1 << i) <= k; i++)
for (j = 1; j - (1 << i) + 1 <= k; j++)
{
p = 1 << (i - 1);
rmq[i][j] = rmq[i - 1][j];
if (niv[rmq[i - 1][j]] > niv[rmq[i - 1][j + p]])
rmq[i][j] = rmq[i - 1][j + p];
}
/// interogarile
for (i = 1; i <= Q; ++i)
{
fin >> x >> y;
x = P[x]; y = P[y];
if (x > y) swap(x, y);
p = len[y - x + 1];
sol = rmq[p][x];
if (niv[sol] > niv[rmq[p][y - (1 << p) + 1]])
sol = rmq[p][y - (1 << p) + 1];
fout << E[sol]<<"\n";
}
fin.close();
fout.close();
return 0;
}