Cod sursa(job #379836)

Utilizator DraStiKDragos Oprica DraStiK Data 4 ianuarie 2010 10:00:21
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.52 kb
#include <algorithm>
#include <vector>
using namespace std;

#define pb push_back
#define DIM 100005
#define LOG 20

int e[2*DIM],l[2*DIM],lg[2*DIM],f[DIM];
vector <int> lst[DIM];
int rmq[LOG][4*DIM];
int n,m,p;

void read ()
{
    int i,x;

    scanf ("%d%d",&n,&m);
    for (i=2; i<=n; ++i)
    {
        scanf ("%d",&x);
        lst[x].pb (i);
    }
}

void df (int nod,int lev)
{
    int i;

    e[++p]=nod;
    l[p]=lev;
    f[nod]=p;
    for (i=0; i<(int)lst[nod].size (); ++i)
    {
        df (lst[nod][i],lev+1);
        e[++p]=nod;
        l[p]=lev;
    }
}

void build_rmq ()
{
    int i,j;

    for (i=2; i<=p; ++i)
        lg[i]=lg[i>>1]+1;
    for (i=1; i<=p; ++i)
        rmq[0][i]=i;
    for (i=1; (1<<i)<p; ++i)
        for (j=1; j<=p-(1<<i); ++j)
            if (l[rmq[i-1][j]]<l[rmq[i-1][j+(1<<(i-1))]])
                rmq[i][j]=rmq[i-1][j];
            else
                rmq[i][j]=rmq[i-1][j+(1<<(i-1))];
}

void solve ()
{
    int i,x,y,lung;

    for (i=1; i<=m; ++i)
    {
        scanf ("%d%d",&x,&y);
        x=f[x];
        y=f[y];
        if (x>y)
            swap (x,y);
        lung=lg[y-x+1];
        if (l[rmq[lung][x]]<l[rmq[lung][y-(1<<lung)+1]])
            printf ("%d\n",e[rmq[lung][x]]);
        else
            printf ("%d\n",e[rmq[lung][y-(1<<lung)+1]]);
    }
}

int main ()
{
    freopen ("lca.in","r",stdin);
    freopen ("lca.out","w",stdout);

    read ();
    df (1,0);
    build_rmq ();
    solve ();

    return 0;
}