Pagini recente » Cod sursa (job #3308665) | Cod sursa (job #3317820) | Cod sursa (job #1090958) | Cod sursa (job #952108) | Cod sursa (job #3321995)
#include <bits/stdc++.h>
#define NMAX 100001
#define LOG 20
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
vector<int> fii[NMAX];
int nivel[NMAX]; ///nivelul fiecarui nod
int lg[NMAX*2]; ///logaritmul fiecarui numar
int rmq[LOG][NMAX*2]; ///rmq pe reprezentarea euler a arborelui
int prima[NMAX*2]; ///prima aparitie a fiecarui nod in reprezentarea euler a arborelui
int cnt=0;
void dfs(int nod) ///calculam nivelul fiecarui nod si reprezentarea euler a arborelui
{
rmq[0][++cnt]=nod;
prima[nod]=cnt;
for(auto& fiu : fii[nod])
{
nivel[fiu]=1+nivel[nod];
dfs(fiu);
rmq[0][++cnt]=nod;
}
}
int min_nivel(int nod1, int nod2)
{
if(nivel[nod1]<nivel[nod2]) return nod1;
else return nod2;
}
void precalc() ///precalculeaza rmq
{
for(int i=2; i<=cnt; i++) lg[i]=lg[i>>1]+1;
for(int e=1; (1<<e)<=cnt; e++)
{
for(int i=1; i<=cnt-e; i++)
rmq[e][i]=min_nivel(rmq[e-1][i], rmq[e-1][i+(1<<(e-1))]);
}
}
int lca(int nod1, int nod2)
{
int poz1=prima[nod1], poz2=prima[nod2];
if(poz1>poz2)
{
swap(nod1, nod2);
swap(poz1, poz2);
}
int dif=poz2-poz1+1;
int e=lg[dif];
return min_nivel(rmq[e][poz1], rmq[e][poz2-(1<<e)+1]);
}
int main()
{
int n, m;
in >> n >> m;
for(int i=2; i<=n; i++)
{
int tata;
in >> tata;
fii[tata].push_back(i);
}
dfs(1);
precalc();
while(m--)
{
int u, v;
in >> u >> v;
out << lca(u, v) << "\n";
}
return 0;
}