Pagini recente » Cod sursa (job #942771) | Cod sursa (job #2231679) | Cod sursa (job #822837) | Cod sursa (job #11824) | Cod sursa (job #3124936)
#include <fstream>
#include <vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
const int NMAX = 1e5 + 5;
const int LOGMAX = 30;
int n, Q;
vector<int> Fii[NMAX + 1];
bool viz[NMAX + 1];
int Euler[3 * NMAX + 1], ind_E;
int Nivel[NMAX + 1];
int Pozitie[NMAX + 1];
int RMQ[3 * NMAX + 1][LOGMAX + 2];
int LOG[3 * NMAX + 1];
void DFS_Euler(int Nod, int Nivel_Curent)
{
viz[Nod] = 1;
Nivel[Nod] = Nivel_Curent;
Euler[++ind_E] = Nod;
Pozitie[Nod] = ind_E;
for(int Fiu : Fii[Nod])
{
if(!viz[Fiu])
{
DFS_Euler(Fiu, Nivel_Curent + 1);
Euler[++ind_E] = Nod;
}
}
}
void PreCalcRMQ()
{
for(int i = 2; i <= ind_E; i++)
LOG[i] = LOG[i / 2] + 1;
for(int i = 1; i <= ind_E; i++)
RMQ[i][0] = Euler[i];
for(int k = 1; (1 << k) <= ind_E; k++)
for(int i = 1; i + (1 << k) - 1 <= ind_E; i++)
{
int Nivel1 = Nivel[RMQ[i][k - 1]];
int Nivel2 = Nivel[RMQ[i + (1 << (k - 1))][k - 1]];
if(Nivel1 < Nivel2)
RMQ[i][k] = RMQ[i][k - 1];
else
RMQ[i][k] = RMQ[i + (1 << (k - 1))][k - 1];
}
}
int LCA(int x, int y)
{
int PozitieX = Pozitie[x];
int PozitieY = Pozitie[y];
if(PozitieX > PozitieY)
swap(PozitieX, PozitieY);
int k = LOG[PozitieY - PozitieX + 1];
return min(RMQ[PozitieX][k], RMQ[PozitieY - (1 << k) + 1][k]);
}
int main()
{
cin >> n >> Q;
for(int i = 2; i <= n; i++)
{
int x;
cin >> x;
Fii[x].push_back(i);
}
DFS_Euler(1, 1);
PreCalcRMQ();
while(Q--)
{
int x, y;
cin >> x >> y;
cout << LCA(x, y) << '\n';
}
return 0;
}