Cod sursa(job #1196990)

Utilizator rzvrzvNicolescu Razvan rzvrzv Data 10 iunie 2014 09:37:42
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.73 kb
#include<cstdio>
#include<vector>

using namespace std;

int e[200003],niv[200003],ap[100003],st,dr,n,m,x,y,Esol,sol,lg,a[400003];
vector<int> d[100003];

void eulerize(int nod,int nivel)
{
    e[++lg]=nod;
    niv[lg]=nivel;
    ap[nod]=lg;
    for(vector<int> ::iterator it=d[nod].begin();it!=d[nod].end();it++)
    {
        eulerize(*it,nivel+1);
        e[++lg]=nod;
        niv[lg]=nivel;
    }
}

void arbintize(int nod,int st,int dr)
{
    int nod1,nod2,mij;
    if(st==dr)
    {
        a[nod]=st;
        return;
    }
    mij=(st+dr)/2;
    nod1=nod<<1;
    nod2=nod1+1;
    arbintize(nod1,st,mij);
    arbintize(nod2,mij+1,dr);
    if(niv[a[nod1]]<=niv[a[nod2]])
    {
        a[nod]=a[nod1];
    }
    else
    {
        a[nod]=a[nod2];
    }
}

void interogare(int nod,int li,int lf)
{
    int mij,nod1,nod2;
        if(st<=li && lf<=dr)
        {
                if(niv[a[nod]] < Esol)
                        sol=e[a[nod]],
                        Esol=niv[a[nod]];
                return;
        }
    mij=(li+lf)/2;
        nod1=nod << 1;
        nod2=nod1 | 1;
        if(st<=mij) interogare(nod1, li, mij);
        if(mij<dr) interogare(nod2, mij+1, lf);
}

int lca(int x,int y)
{
    st=ap[x];dr=ap[y];
    if(st>dr)
    {
        swap(st,dr);
    }
    sol=Esol=0x3f3f3f3f;
    interogare(1,1,lg);
    return sol;
}

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    scanf("%d%d",&n,&m);
    int i;
    for(i=2;i<=n;i++)
    {
        scanf("%d",&x);
        d[x].push_back(i);
    }
    eulerize(1,0);
    arbintize(1,1,lg);
    for(i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        printf("%d\n",lca(x,y));
    }
}