Cod sursa(job #546858)

Utilizator eudanipEugenie Daniel Posdarascu eudanip Data 5 martie 2011 16:21:45
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.44 kb
#include<stdio.h>
#include<vector>
using namespace std;

#define pb push_back
#define NMAX 100004

vector<int> vec[NMAX];
int poz[NMAX],euler[2*NMAX+5];
int rmq[21][2*NMAX+5];
int h[NMAX];
int prep[2*NMAX+5];
int n,m,nr;

void dfs(int nod)
{
    int i,lim=vec[nod].size();
    poz[nod]=++nr;
    euler[nr]=nod;
    for(i=0;i<lim;i++)
    {
        h[vec[nod][i]]=h[nod]+1;
        dfs(vec[nod][i]);
        euler[++nr]=nod;
    }
}

inline int lca(int a,int b)
{
    int aux,l;
    
    a=poz[a]; b=poz[b];
    if(a>b)
    {
        aux=a;
        a=b;
        b=aux;
    }
    l=prep[b-a+1];
    if(h[rmq[l][a]]<h[rmq[l][b-(1<<l)+1]])
        return rmq[l][a];
    return rmq[l][b-(1<<l)+1];
}

int main ()
{
    int i,j,l,t,a,b;
    
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(i=2;i<=n;i++)
    {
        scanf("%d",&t);
        vec[t].pb(i);
    }
    dfs(1);
    for(i=1;i<=nr;i++)
        rmq[0][i]=euler[i];
    for(l=1;(1<<l)<=nr;l++)
        for(j=1;j<=nr-(1<<l)+1;j++)
            if(h[rmq[l-1][j]]<h[rmq[l-1][j+(1<<(l-1))]])
                rmq[l][j]=rmq[l-1][j];
            else
                rmq[l][j]=rmq[l-1][j+(1<<(l-1))];
    prep[1]=0;
    for(i=2;i<=nr;i++)
        prep[i]=prep[i/2]+1;
        
    for(i=1;i<=m;i++)
    {
        scanf("%d%d",&a,&b);
        printf("%d\n",lca(a,b));
    }
    return 0;
}