Pagini recente » Cod sursa (job #1313514) | Cod sursa (job #2076642) | Rating Silviu Suciu (silviusuciu) | Cod sursa (job #1337295) | Cod sursa (job #3212928)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");ofstream fout("lca.out");
const int N=100007;
const int N_TUR=100007*2+1;
int n,q;
vector<int>g[N];
int ordine[N_TUR],nivel[N_TUR],poz_tur,aparitie_tur[N];
int tabel_RMQ[19][N_TUR],exponent2[N_TUR];
void Citire()
{
fin >> n >> q;
for(int i=2;i<=n;i++)
{
int tata;
fin >> tata;
g[tata].push_back(i);
}
}
void Adaugare_ordine(int x,int adancime)
{
ordine[++poz_tur]=x;
nivel[poz_tur]=x;
aparitie_tur[x]=poz_tur;
}
inline void Tur_eulerian(int x,int adancime)
{
Adaugare_ordine(x,adancime);
for(auto y:g[x])
{
Tur_eulerian(y,adancime+1);
Adaugare_ordine(x,adancime);
}
}
void Generare_RMQ()
{
for(int i=2;i<=2*n-1;i++) /// / ///
exponent2[i]=exponent2[i/2]+1;
for(int i=1;i<=poz_tur;i++)
tabel_RMQ[0][i]=i;
for(int i=1;i<=exponent2[poz_tur];i++)
{
int putere=(1<<i);
for(int j=1;j<=poz_tur-putere+1;j++)
{
if( nivel[ tabel_RMQ[i-1][j] ]<nivel[ tabel_RMQ[i-1][j+putere/2] ] )
tabel_RMQ[i][j]=tabel_RMQ[i-1][j];
else
tabel_RMQ[i][j]=tabel_RMQ[i-1][j+putere/2];
}
}
}
int LCA(int x,int y)
{
int st= min( aparitie_tur[x],aparitie_tur[y] );
int dr= max( aparitie_tur[x],aparitie_tur[y] );
int expxy = exponent2[ dr-st+1 ];
int putere = 1<<expxy;
if( nivel[ tabel_RMQ[expxy][st] ]<nivel[ tabel_RMQ[expxy][dr-putere+1] ] )
return ordine[tabel_RMQ[expxy][st]];
return ordine[tabel_RMQ[expxy][dr-putere+1]];
}
int main()
{
Citire();
Tur_eulerian(1,1);
Generare_RMQ();
for(int i=1;i<=q;i++)
{
int x,y;
fin >> x >> y;
fout << LCA(x,y) << "\n";
}
fin.close();fout.close();
return 0;
}