Cod sursa(job #1165612)

Utilizator lianaliana tucar liana Data 2 aprilie 2014 19:37:51
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.5 kb
#include<stdio.h>
#include<vector>
using namespace std;
#define nmax 100005
#define lpmax 3*nmax
#define pmax 20
int n, m, i, ne, log, x, y, aux, rez;
int t[nmax], niv[nmax], poz[nmax], p[lpmax], lg[lpmax];
int rmq[lpmax][pmax];
vector <int> ma[nmax];

void citire()
{
    scanf("%ld %ld",&n,&m);
    for (i=2;i<=n;i++)
    {
        scanf("%ld",&t[i]);
        ma[t[i]].push_back(i);
    }
}

void dfs(int x)
{
    vector <int> ::iterator it;
    niv[x]=niv[t[x]]+1;
    p[++ne]=x;
    if (poz[x]==0)
        poz[x]=ne;
    for (it=ma[x].begin();it!=ma[x].end();it++)
    {
        dfs(*it);
        p[++ne]=x;
    }
}

void constr_rmq()
{
    for(i=1;i<=ne;i++)
    {
        rmq[i][0]=p[i];
        if (i>1)
            lg[i]=lg[i/2]+1;
    }
    for (log=1;(1<<log)<=ne;log++)
        for (i=1;i+(1<<log)<=ne;i++)
        {
            rmq[i][log]=rmq[i][log-1];
            if (niv[rmq[i][log]]>niv[rmq[i+(1<<(log-1))][log-1]])
                rmq[i][log]=rmq[i+(1<<(log-1))][log-1];
        }
}

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    citire();
    dfs(1);
    constr_rmq();
    for (i=1;i<=m;i++)
    {
        scanf("%ld %ld",&x,&y);
        x=poz[x];   y=poz[y];
        if (x>y)
        {   aux=x;  x=y;    y=aux;  }
        log=lg[y-x+1];
        rez=rmq[x][log];
        if (niv[rez]>niv[rmq[y-(1<<log)+1][log]])
            rez=rmq[y-(1<<log)+1][log];
        printf("%ld\n",rez);

    }
    return 0;
}