Cod sursa(job #768970)

Utilizator geniucosOncescu Costin geniucos Data 17 iulie 2012 23:12:49
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.64 kb
#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
int maxi,j,p,ul1,nr,i,ul,x1,y1,n,m,t[100002],ap[100002],a[200002],niv[100002],l[100002],mi[100002][19],pr[100002];
vector < int > h[100002];
vector < int >::iterator it;
queue < int > cc;
int ras(int st,int dr)
{
    int j=l[dr-st+1];
    if(niv[mi[st][j]]<niv[mi[dr-(1<<j)+1][j]]) return mi[st][j];
    return mi[dr-(1<<j)+1][j];
}
int main()
{
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
scanf("%d %d",&n,&m);
for(i=2;i<=n;i++)
{
    scanf("%d",&t[i]);
    h[t[i]].push_back(i);
}
cc.push(1);
niv[1]=1;
while(!cc.empty())
{
    x1=cc.front();
    cc.pop();
    for(it=h[x1].begin();it!=h[x1].end();it++)
        if(niv[*it]==0)
        {
            niv[*it]=niv[x1]+1;
            cc.push(*it);
        }
}
ul=1;
nr=1;
a[nr]=1;
while(1)
{
    if(!h[ul].empty())
    {
        ul1=ul;
        ul=h[ul][0];
        h[ul1].erase(h[ul1].begin());
        nr++;
        a[nr]=ul;
    }
    else
    {
        ul=t[ul];
        if(ul==0) break;
        nr++;
        a[nr]=ul;
    }
}
p=0;
for(i=1;i<=nr;i++)
{
    l[i]=p;
    if(i==(1<<(p+1))-1) p++;
}
for(i=nr;i>=1;i--)
{
    //niv[a[i]];
    mi[i][0]=a[i];
    for(j=1;(1<<j)+i-1<=nr;j++)
    {
        if(niv[mi[i][j-1]]<niv[mi[i+(1<<(j-1))][j-1]]) mi[i][j]=mi[i][j-1];
        else mi[i][j]=mi[i+(1<<(j-1))][j-1];
    }
}
for(i=1;i<=nr;i++)
    if(pr[a[i]]==0) pr[a[i]]=i;
for(i=1;i<=m;i++)
{
    scanf("%d",&x1);
    scanf("%d",&y1);
    if(pr[x1]<=pr[y1]) printf("%d\n",ras(pr[x1],pr[y1]));
    else printf("%d\n",ras(pr[y1],pr[x1]));
}
return 0;
}