Cod sursa(job #867548)

Utilizator stoicatheoFlirk Navok stoicatheo Data 29 ianuarie 2013 20:31:21
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.43 kb
#include<stdio.h>
#include<vector>
#define Nmax 100010
using namespace std;
 
int M[2*Nmax+10][20],E[2*Nmax+10],H[2*Nmax+10],i,j,x,y,n,m,k,poz[Nmax];
vector<int> V[Nmax];
 
void dfs(int nod,int h)
{
    E[++k]=nod;
    H[k]=h;
    if(!poz[nod]) poz[nod]=k;
     
    int N=V[nod].size(),t;
     
    for(t=0;t<N;t++)
    {
        dfs(V[nod][t],h+1);
        E[++k]=nod;
        H[k]=h;
    }
}   
 
 
void rmq()
{
    int j,i,N=2*n-1;
     
    for(i=1;i<=N;i++)
        M[i][0]=i;
     
    for(j=1; (1<<j) <= N ; j++)
        for(i=1; i + (1<<j) -1 <= N; i++)
            if(H[M[i][j-1]] <= H[M[i+(1<<(j-1))][j-1]])
                M[i][j]=M[i][j-1];
            else M[i][j]=M[i+(1<<(j-1))][j-1];
}
 
int lca(int i, int j)
{
    int k=0,val=j-i+1,p;
     
    while(val!=1)
    {
        k++;
        val>>=1;
    }
     
    if( H[M[i][k]] <= H[M[j-(1<<k)+1][k]] )
        p=M[i][k];
    else p=M[j-(1<<k)+1][k];
     
    return E[p];
}
 
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",&x);
        V[x].push_back(i);
    }
     
    dfs(1,0);
    rmq();
    for(i=1;i<=m;i++)
    {
        scanf("%d %d",&x, &y);
        if(poz[x]<poz[y])
            printf("%d\n",lca(poz[x],poz[y]));
        else printf("%d\n",lca(poz[y],poz[x]));
    }
    return 0;
}