Pagini recente » Cod sursa (job #2845979) | Arhiva de probleme | Profil Samoila_Alexandru | Cod sursa (job #24879) | Cod sursa (job #2360167)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ofstream fo("lca.out");
ifstream fi("lca.in");
int n,m,a,N;
vector<int> vecini[100005];
vector<int> ordonatEuler;
vector<int> log2;
int first[100005];
int rmq[25][100005];
int nivel[100005];
void DFS(int nod,int nnivel)
{
ordonatEuler.push_back(nod);
nivel[nod]=nnivel;
for(int vec:vecini[nod])
{
DFS(vec,nnivel+1);
ordonatEuler.push_back(nod);
}
}
int main()
{
fi>>n>>m;
for(int i=2; i<=n; i++)
{
fi>>a;
vecini[a].push_back(i);
}
DFS(1,0);
N=ordonatEuler.size()-1;
log2.push_back(0);
log2.push_back(0);
for(int i=2; i<=N; i++)
log2.push_back(log2[i/2]+1);
for(int i=0; i<=N; i++)
{
rmq[0][i]=ordonatEuler[i];
if(first[ordonatEuler[i]]==0)
first[ordonatEuler[i]]=i;
}
for(int p=1; p<=log2[N]+1; p++) ///putere de 2
for(int j=0; j<=N-(1<<p)+1 ; j++) /// elem
if(nivel[rmq[p-1][j] ]<nivel[ rmq[p-1][j+(1<<(p-1)) ]])
rmq[p][j]=rmq[p-1][j];
else
rmq[p][j]=rmq[p-1][j+(1<<(p-1))];
for(int i=1; i<=m; i++)
{
int nod1,nod2,l,lg;
fi>>nod1>>nod2;
nod1=first[nod1]; ///primele poz
nod2=first[nod2];
if(nod1>nod2)swap(nod1,nod2);
l=nod2-nod1+1;
lg=log2[l];
if(nivel[rmq[lg][nod1] ]< nivel[ rmq[lg][nod2-(1<<lg)+1 ]] )
fo<<rmq[lg][nod1]<<'\n';
else
fo<<rmq[lg][nod2-(1<<lg)+1]<<'\n';
}
fi.close();
fo.close();
return 0;
}