Cod sursa(job #1201395)

Utilizator DenisacheDenis Ehorovici Denisache Data 25 iunie 2014 03:41:04
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.46 kb
#include <cstdio>
#include <vector>
using namespace std;
#define forA(V) for (typeof (V).begin() it=(V).begin();it!=(V).end();it++)
#define pb push_back
#define MAXN 100005
int First[MAXN],H[MAXN<<1],lg[MAXN<<1],L[MAXN<<1],rmq[20][MAXN<<1],K,N,M;
vector <int> G[MAXN];
void DFS(int nod,int lev)
{
    H[++K]=nod;
    L[K]=lev;
    First[nod]=K;
    forA(G[nod])
    {
        DFS(*it,lev+1);
        H[++K]=nod;
        L[K]=lev;
    }
}
void rmqGen()
{
    for (register int i=1;i<=K;i++)
    {
        rmq[0][i]=i;
        if (i>=2) lg[i]=lg[i>>1]+1;
    }
    for (register int i=1;(1<<i)<=K;i++)
    {
        for (register int j=1;j<=K-(1<<i)+1;j++)
        {
            int l=1<<(i-1);
            if (L[rmq[i-1][j]]<L[rmq[i-1][j+l]]) rmq[i][j]=rmq[i-1][j];
            else rmq[i][j]=rmq[i-1][j+l];
        }
    }
}
int lca(int x,int y)
{
    int a=First[x],b=First[y];
    if (a>b){int aux=a; a=b; b=aux;}
    int diff=b-a+1,l=lg[diff],sh=diff-(1<<l);
    if (L[rmq[l][a]]<L[rmq[l][a+sh]]) return H[rmq[l][a]];
    else return H[rmq[l][a+sh]];
}
int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    scanf("%d %d\n",&N,&M);
    for (register int i=2;i<=N;i++)
    {
        int x;
        scanf("%d",&x);
        G[x].pb(i);
    }
    DFS(1,0);
    rmqGen();
    for (register int i=1;i<=M;i++)
    {
        int x,y;
        scanf("%d %d",&x,&y);
        printf("%d\n",lca(x,y));
    }
}