Cod sursa(job #1149501)

Utilizator lianaliana tucar liana Data 21 martie 2014 22:30:32
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.6 kb
#include<stdio.h>
#include<vector>
using namespace std;
#define nmax 100005
#define pmax 22
int i, n, ne, nivv, t, log, m, a, b, aux, lung, rez;
int niv[nmax], lg[4*nmax], p[4*nmax], poz[nmax];
int rmq[pmax][4*nmax];
vector <int> ma[nmax];

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

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

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)-1<=ne;i++)
        {
            if (niv[rmq[i][log-1]]<niv[rmq[i+(1<<(log-1))][log-1]])
                rmq[i][log]=rmq[i][log-1];
            else
                rmq[i][log]=rmq[i+(1<<(log-1))][log-1];
        }
}

void rezolvare()
{
    for (i=1;i<=m;i++)
    {
        scanf("%ld %ld",&a,&b);
        if (poz[a]>poz[b])
        {   aux=a;  a=b;    b=aux;  }
        a=poz[a];   b=poz[b];
        lung=b-a+1;
        log=lg[lung];
        rez=rmq[a][log];
        if (niv[rez]>niv[rmq[b-(1<<log)+1][log]])
            rez=rmq[b-(1<<log)+1][log];
        printf("%ld\n",rez);
    }
}

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    citire();
    dfs(1);
    constr_rmq();
    rezolvare();
    return 0;
}