Pagini recente » Cod sursa (job #192634) | Cod sursa (job #2522079) | Cod sursa (job #2274551) | Cod sursa (job #2487922) | Cod sursa (job #2869899)
#include <fstream>
#include <vector>
#include <cmath>
#include <iostream>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, m;
int stramos[30][100009];
int nivel[100009] , vizitat[1000009];
vector <int> v[100009];
int logaritm;
void calc_stramosi()
{
for(int exp=1;exp<=logaritm;exp++)
{
for(int nod=1;nod<=n;nod++)
{
stramos[exp][nod]=stramos[exp-1][stramos[exp-1][nod]];
//cout<<stramos[exp][nod]<<' ';
}
//cout<<endl;
}
}
void egalizare(int &a, int &b)
{
int dif=nivel[b]-nivel[a];
for(int i=logaritm;i>=0;i--)
{
int pow=(1<<i);
if(pow<=dif)
{
dif-=pow;
b=stramos[i][b];
}
}
}
int lca(int a, int b)
{
if(nivel[a]>nivel[b])
{
int aux=a;
a=b;
b=aux;
}
if(nivel[a]!=nivel[b])
egalizare(a,b);
int stram_a=a, stram_b=b;
if(stram_a==stram_b)
{
return stram_a;
}
for(int i=16;i>=0;i--)
{
if(stramos[i][stram_a]!=stramos[i][stram_b])
{
stram_a=stramos[i][stram_a];
stram_b=stramos[i][stram_b];
}
}
return stramos[0][stram_a];
}
void dfs(int x, int niv)
{
vizitat[x]=1;
nivel[x]=niv;
for(int i=0;i<v[x].size();i++)
{
int vecin=v[x][i];
if(vizitat[vecin]==0)
{
dfs(vecin,niv+1);
}
}
}
int main()
{
fin>>n>>m;
logaritm=log2(n);
for(int i=2;i<=n;i++)
{
fin>>stramos[0][i];
v[stramos[0][i]].push_back(i);
//v[i].push_back(stramos[0][i]);
}
stramos[0][1]=1;
calc_stramosi();
dfs(1,1);
for(int i=1;i<=m;i++)
{
int a, b;
fin>>a>>b;
fout<<lca(a,b)<<'\n';
}
return 0;
}