Cod sursa(job #409740)

Utilizator DraStiKDragos Oprica DraStiK Data 3 martie 2010 20:40:59
Problema Lowest Common Ancestor Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.53 kb
#include <algorithm>
#include <vector>
using namespace std;

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

int e[DIM>>1],l[DIM>>1],lg[DIM>>1],f[DIM];
int rmq[LOG][DIM>>4];
vector <int> g[DIM];
int n,m,p;

void read ()
{
    int i,x;

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

void df (int nod,int lev)
{
    vector <int> :: iterator it;

    f[nod]=++p;
    e[p]=nod;
    l[p]=lev;
    for (it=g[nod].begin (); it!=g[nod].end (); ++it)
    {
        df (*it,lev+1);
        ++p;
        e[p]=nod;
        l[p]=lev;
    }
}

void solve ()
{
    int i,j;

    df (1,0);
    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 query ()
{
    int i,x,y,dif;

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

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

    read ();
    solve ();
    query ();

    return 0;
}