Pagini recente » Cod sursa (job #3240547) | Cod sursa (job #1928015) | Cod sursa (job #1339300) | Cod sursa (job #2553299) | Cod sursa (job #654341)
Cod sursa(job #654341)
#include<fstream>
#include<vector>
#include<iostream>
using namespace std;
int n,m,poz[100100],N,rmq[200100][20],minpoz[201000][20],put[200100];
vector <int> fiu[100100],euler,adancime;
vector <int>::iterator it;
inline void DFS(int nod,int niv)
{
vector <int>::iterator it;
for(it=fiu[nod].begin();it!=fiu[nod].end();it++)
{
euler.push_back(nod);
adancime.push_back(niv);
poz[nod]=N++;
DFS(*it,niv+1);
}
euler.push_back(nod);
adancime.push_back(niv);
poz[nod]=N++;
}
inline void Precalculare_RMQ()
{
int i,k,lim,lg;
put[1]=0;
for(i=2;i<=N;i++)
put[i]=put[i/2]+1;
for(i=1;i<=N;i++)
{
rmq[i][0]=adancime[i];
minpoz[i][0]=i;
}
for(k=1;(1<<k)<=N;k++)
{
lim=N-(1<<k)+1;
for(i=1;i<=lim;i++)
{
lg=(1<<(k-1));
if(rmq[i][k-1]<rmq[i+lg][k-1])
{
rmq[i][k]=rmq[i][k-1];
minpoz[i][k]=minpoz[i][k-1];
}
else
{
rmq[i][k]=rmq[i+lg][k-1];
minpoz[i][k]=minpoz[i+lg][k-1];
}
}
}
}
int main()
{
int i,tata,x,y,st,dr,lg,dif,exp;
ifstream fin("lca.in");
ofstream fout("lca.out");
fin>>n>>m;
for(i=2;i<=n;i++)
{
fin>>tata;
fiu[tata].push_back(i);
}
// adaug pe pozitia 0 elemente fictive
euler.push_back(0);
adancime.push_back(0);
N=1;
//
DFS(1,1); //fac parcurgere euler si construiesc si vectorul de adancimi
N--;
Precalculare_RMQ(); //fac RMQ pentru vectorul de adancimi
//intrucat LCA(i,j)=nodul cu cea mai mica adancime din parcurgerea euler dintre nodurile i si j
for(i=1;i<=m;i++)
{
fin>>x>>y;
st=min(poz[x],poz[y]);
dr=max(poz[x],poz[y]);
lg=dr-st+1;
exp=put[lg];
dif=lg-(1<<exp);
if(rmq[st][exp]<rmq[st+dif][exp])
{
fout<<euler[minpoz[st][exp]]<<"\n";
}
else
{
fout<<euler[minpoz[st+dif][exp]]<<"\n";
}
}
fin.close();
fout.close();
return 0;
}