Cod sursa(job #573570)

Utilizator jupanubv92Popescu Marius jupanubv92 Data 6 aprilie 2011 13:12:29
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.5 kb
#include <cstdio>
#include <cstring>
#include <algorithm>
#define Nmx 100001
#define INF 0x3f3f3f3f
using namespace std;

struct nod{int inf;nod *urm;};

nod *G[Nmx];
int n,m,A,B,nr,First[Nmx],L[Nmx<<1],H[Nmx<<1];
int lg[Nmx<<1];
int R[20][Nmx<<1];

void add(int x,int y)
{
    nod *aux=new nod;
    aux->inf = y;
    aux->urm = G[x];
    G[x]=aux;
}

void read()
{
    int x;
    scanf("%d%d",&n,&m);
    for(int i=2;i<=n;++i)
    {
        scanf("%d",&x);
        add(x,i);
    }
}

void dfs(int nd,int niv)
{
    L[++nr]=niv;
    H[nr]=nd;
    First[nd]=nr;
    for(nod *p=G[nd];p;p=p->urm)
    {
        dfs(p->inf,niv+1);
        L[++nr]=niv;
        H[nr]=nd;
    }
}

void RMQ()
{
    for(int i=1;i<=nr;++i)
        R[0][i]=i;
    for(int i=1;(1<<i)<nr;++i)
        for(int j=1;j<=nr-(1<<i);++j)
        {
            int l = (1<<(i-1));
            R[i][j]=R[i-1][j];
            if(L[R[i][j]]>L[R[i-1][j+l]])
                R[i][j]=R[i-1][j+l];
        }
}

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    read();
    dfs(1,0);
    RMQ();
    int x,s,y,dif,l;
    for(int i=2;i<=nr;++i)
        lg[i]=lg[i/2]+1;
    for(;m;m--)
    {
        scanf("%d%d",&x,&y);
        A=First[x];B=First[y];
        if(A>B) A^=B^=A^=B;
        dif=(B-A+1);
        l=lg[dif];
        s=R[l][A];
        if(L[s]>L[R[l][A+(dif-(1<<l))]])
            s=R[l][A+(dif-(1<<l))];
        printf("%d\n",H[s]);
    }
    return 0;
}