Cod sursa(job #409324)

Utilizator RobytzzaIonescu Robert Marius Robytzza Data 3 martie 2010 16:28:15
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.64 kb
#include <stdio.h>
#include <vector>
#define Size 1000000
#define mi(a,b) niv[a]<niv[b]?a:b

using namespace std;


int n,m;
int put[Size];
int rmq[20][Size]; //RMQ
int niv[Size]; //nivelul pe care se afla
int p_min[Size]; //poz_min
int E[Size]; //euler
int viz[Size];
vector <int> V[Size]; //copiii :))
int nr_e;

void citire()
{
    int x;
    scanf ("%d %d",&n,&m);
    for (int i=2;i<=n;i++)
    {
        scanf ("%d ",&x);
        V[x].push_back(i);
    }
}

void df(int n)
{
    viz[n]=1;
    for (int i=0; i<V[n].size(); i++)
        if (viz[V[n][i]]==0)
        {
            int n1=V[n][i];
            E[++nr_e]=n1;
            viz[n1]=1;
            if (p_min[n1]==0)
                p_min[n1]=nr_e;
            niv[n1]=niv[n]+1;
            df(n1);
            E[++nr_e]=n;
        }
}

void RMQ()
{
    int n=nr_e;
    for (int i=2;i<=n;i++)
    {
        put[i]=put[i>>1]+1;
        rmq[0][i]=E[i];
    }
    rmq[0][1]=E[1];
    for (int i=1; i<=put[n];i++)
        for (int j=1;j<=n-(1<<(i))+1;j++)
            rmq[i][j]=mi(rmq[i-1][j],rmq[i-1][j+(1<<(i-1))]);
}


void afish()
{
    int a,b,dif;
    for (int i=0;i<m;i++)
    {
        scanf ("%d %d",&a,&b);
        if (p_min[a]>p_min[b])
        {
            int t=a;
            a=b;
            b=t;
        }
        dif=put[p_min[b]-p_min[a]+1];
        printf("%d\n",mi(rmq[dif][p_min[a]] ,rmq[dif][p_min[b]-(1<<dif)+1]));
    }
}

int main ()
{
    freopen ("lca.in","r",stdin);
    freopen ("lca.out","w",stdout);
    citire();
    E[nr_e=1]=1;
    p_min[1]=1;
    df(1);
    RMQ();
    afish();
    return 0;
}