Cod sursa(job #1117002)

Utilizator thewildnathNathan Wildenberg thewildnath Data 22 februarie 2014 22:56:33
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.74 kb
#include<stdio.h>
#include<vector>
using namespace std;

#define NMAX 100005

int n,m;
int nr,niv;
int rmq[20][NMAX*2],first[NMAX],lvl[NMAX*2],log[NMAX];

vector<int>v[NMAX];

void dfs(int nod)
{
    int i;
    ++niv;

    rmq[0][++nr]=nod;
    lvl[nod]=niv;
    if(!first[nod])first[nod]=nr;
    for(i=0;i<v[nod].size();++i)
    {
        dfs(v[nod][i]);
        rmq[0][++nr]=nod;
    }
    --niv;
}

void RMQ()
{
    int i,j,l=1;//maxi,maxj;

    /*maxi=1;
    while((1<<maxi)<=nr)maxi<<=1;
    maxi>>=1;*/

    for(i=1;(1<<i)<nr;++i)
    {
        //maxj=nr-(1<<i)+1;
        l=(1<<(i-1));

        for(j=1;j<=nr-(1<<i);++j)
        {
            rmq[i][j]=rmq[i-1][j];
            if(lvl[rmq[i-1][j+l]]<lvl[rmq[i][j]])
                rmq[i][j]=rmq[i-1][j+l];

            //rmq[i][j]=min(rmq[i-1][j], rmq[i-1][j+l]);
        }
    }
}

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    int i,j,x,y,dif,sol,aux;
    scanf("%d%d",&n,&m);

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

    nr=0;
    dfs(1);
    for(i=2;i<=nr;++i)
        log[i]=log[i>>1]+1;

    RMQ();


    for(i=1;i<=m;++i)
    {
        scanf("%d%d",&x,&y);

        x=first[x];
        y=first[y];

        if(x>y)
        {
            aux=x;
            x=y;
            y=aux;
        }

        dif=y-x+1;
        j=log[dif];
        aux=dif-(1<<j);

        sol=rmq[j][x];

        if(lvl[sol]>lvl[rmq[j][x+aux]])
            sol=rmq[j][x+aux];

        printf("%d\n",sol);


        /*j=1;
        while((1<<j)<=d)++j;
        --j;*/
        //printf("%d\n",min(rmq[j][x] , rmq[j][y-(1<<j)+1]));
    }

    return 0;
}