Mai intai trebuie sa te autentifici.
Cod sursa(job #654340)
Utilizator | Data | 30 decembrie 2011 12:04:02 | |
---|---|---|---|
Problema | Lowest Common Ancestor | Scor | 30 |
Compilator | cpp | Status | done |
Runda | Arhiva educationala | Marime | 1.81 kb |
#include<fstream>
#include<vector>
using namespace std;
int n,m,poz[100100],N,rmq[100100][20],minpoz[100100][20],put[1000100];
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;
}