Pagini recente » Cod sursa (job #300617) | Cod sursa (job #498013) | Cod sursa (job #2451901) | Rating Pantelimon Lucian-Ionut (BlackSilver) | Cod sursa (job #2560298)
#include <bits/stdc++.h>
#define NMAX 100001
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, nr, k, vf[NMAX * 2], urm[NMAX * 2], last[NMAX];
int nre, eul[NMAX * 2], nivel[NMAX * 2], poz[NMAX];
int rmq[18][NMAX * 2];
void adauga(int nod, int tata)
{
vf[++nr] = nod;
urm[nr] = last[tata];
last[tata] = nr;
}
void edfs(int nod, int tata, int niv)
{
eul[++nre] = nod;
nivel[nre] = niv;
poz[nod] = nre;
for(int k = last[nod]; k; k = urm[k])
if( vf[k] != tata )
{
edfs(vf[k], nod, niv+1);
eul[++nre] = nod;
nivel[nre] = niv;
}
}
void RMQ()
{
for(int i=1; i<=nre; i++)
rmq[0][i] = i;
int rMax = log2(nre);
for(int r = 1, l = 1; r<=rMax; r++, l*=2)
for(int i = 1; i <= nre - l*2 + 1; i++)
{
if( nivel[ rmq[r-1][i] ] > nivel[ rmq[r-1][i+l] ] )
rmq[r][i] = rmq[r-1][i+l];
else
rmq[r][i] = rmq[r-1][i];
}
}
int lca(int a, int b)
{
a = poz[a];
b = poz[b];
if(a > b)
swap(a, b);
int r = log2(b - a + 1);
int l = (1<<r);
int pozMin = 0;
if( nivel[ rmq[r][a] ] > nivel[ rmq[r][b - l + 1] ] )
pozMin = rmq[r][b - l + 1] ;
else
pozMin = rmq[r][a] ;
return eul[pozMin];
}
int main()
{
fin>>n>>k;
for(int i=2; i<=n; i++)
{
int x; fin>>x;
adauga(i, x);
adauga(x, i);
}
edfs(1, 0, 1);
RMQ();
for(int a, b, i=1; i<=k; i++)
{
fin>>a>>b;
fout<<lca(a, b)<<'\n';
}
return 0;
}