Pagini recente » Cod sursa (job #2319477) | Cod sursa (job #2358181) | Cod sursa (job #1619616) | Cod sursa (job #2335593) | Cod sursa (job #1378668)
#include <fstream>
#include<vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int pos,val,minim,n,i,t,a,b,start,finish,x,m;
vector<int> v[100010];
int vizitat[100010],level[100010],euler[200010],aint[400010];
void update(int nod,int left,int right)
{
if(left==right)
{
aint[nod]=val;
return;
}
int mij=(left+right)/2;
if(pos<=mij) update(2*nod,left,mij);
else update(2*nod+1,mij+1,right);
if(level[aint[2*nod]]<= level[aint[2*nod+1]])
aint[nod]=aint[2*nod];
else
aint[nod]=aint[2*nod+1];
}
void querry(int nod,int left,int right)
{
if(left>=start&&right<=finish)
{
if(level[aint[nod]]<level[minim])
minim=aint[nod];
return;
}
int mij=(left+right)/2;
if(start<=mij) querry(2*nod,left,mij);
if(finish>mij) querry(2*nod+1,mij+1,right);
}
void dfs(int x,int niv)
{
int i;
//fout<<x<<" ";
euler[++t]=x;
if(vizitat[x]==-1)
vizitat[x]=t;
level[x]=niv;
for(i=0;i<v[x].size();++i)
{
dfs(v[x][i],niv+1);
euler[++t]=x;
//fout<<x<<" ";
}
}
int main()
{
fin>>n>>m;
for(i=2;i<=n;++i)
{
fin>>x;
v[x].push_back(i);
}
for(i=1;i<=n;++i) vizitat[i]=-1;
dfs(1,0); //reprezentarea euler
//for(i=1;i<=t;++i)
// fout<<euler[i]<<" "<<level[euler[i]]<<'\n';
level[0]=1<<30;
//! formare arbore de intervale
for(i=1;i<=t;++i)
{
val=euler[i];
pos=i;
update(1,1,t);
}
//!querry
for(i=1;i<=m;++i)
{
fin>>a>>b;
start=min(vizitat[a],vizitat[b]);
finish=max(vizitat[a],vizitat[b]);
minim=1<<30;
querry(1,1,t);
fout<<minim<<'\n';
}
return 0;
}