Cod sursa(job #409901)

Utilizator DraStiKDragos Oprica DraStiK Data 3 martie 2010 22:03:49
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.92 kb
#include <algorithm>
#include <vector>
using namespace std;

#define pb push_back
#define DIM 100005
#define MAX 10005
#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,poz=MAX-1;
char buff[MAX];

inline void cit (int &nr)
{
    for ( ; !isdigit (buff[poz]); )
        if (++poz==MAX)
        {
            fread (buff,1,MAX,stdin);
            poz=0;
        }
    for (nr=0; isdigit (buff[poz]); )
    {
        nr=nr*10+buff[poz]-'0';
        if (++poz==MAX)
        {
            fread (buff,1,MAX,stdin);
            poz=0;
        }
    }
}

void read ()
{
    int i,x;

    cit (n); cit (m);
    for (i=2; i<=n; ++i)
    {
        cit (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)
    {
        cit (x); cit (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;
}