Cod sursa(job #1116912)

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

#define NMAX 100002

int n,m;
int nr;
int t[NMAX],ord[NMAX],rmq[17][NMAX*2];

vector<int>v[NMAX];
queue<int>q;

void bfs_num()
{
    int i,nod;
    q.push(1);
    while(!q.empty())
    {
        nod=q.front();
        ord[nod]=++nr;
        q.pop();
        for(i=0;i<v[nod].size();++i)
            q.push(v[nod][i]);
    }
}

void dfs(int nod)
{
    int i;
    rmq[0][++nr]=ord[nod];

    for(i=0;i<v[nod].size();++i)
    {
        dfs(v[nod][i]);
        rmq[0][++nr]=ord[nod];
    }
}

void RMQ()
{
    int i,j,maxi,maxj;

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

    for(i=1;i<=maxi;++i)
    {
        maxj=nr-(1<<i)+1;
        for(j=1;j<=maxj;++j)
            rmq[i][j]=min(rmq[i-1][j], rmq[i-1][j+(1<<(i-1))]);
    }
}

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

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

    // Numerotare
    bfs_num();
    nr=0;
    dfs(1);

    RMQ();

    //for(i=1;i<=nr;++i)
    //    printf("%d ",rmq[0][i]);

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

        for(j=1;j<=nr;++j)
            if(rmq[0][j]==ord[x])
                break;
        x=j;
        for(;j<=nr;++j)
            if(rmq[0][j]==ord[y])
                break;
        y=j;
        d=y-x+1;

        j=1;
        while((1<<j)<=d)++j;
        --j;

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

    return 0;
}