Cod sursa(job #1014558)

Utilizator mirceadinoMircea Popoveniuc mirceadino Data 22 octombrie 2013 21:22:43
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.44 kb
#include<cstdio>
#include<vector>
#include<algorithm>
#define NMAX 100000+5
using namespace std;
int N,M,NE;
vector<int> T[NMAX];
int Euler[2*NMAX];
int Nivel[2*NMAX];
int First[NMAX];
int RMQ[18][2*NMAX];
void DFS(int x,int n)
{
    vector<int>::iterator it;
    NE++;
    Euler[NE]=x;
    Nivel[NE]=n;
    First[x]=NE;
    RMQ[0][NE]=NE;
    for(it=T[x].begin();it!=T[x].end();it++)
    {
        DFS(*it,n+1);
        NE++;
        Euler[NE]=x;
        Nivel[NE]=n;
        RMQ[0][NE]=NE;
    }
}
void Do_RMQ()
{
    int i,j,k,p,a,b;
    for(i=1,p=2;p<=NE;i++,p<<=1)
    {
        for(j=1;j+p<=NE;j++)
        {
            k=p>>1;
            a=RMQ[i-1][j];
            b=RMQ[i-1][j+k];
            if(Nivel[a]<=Nivel[b]) RMQ[i][j]=a;
            else RMQ[i][j]=b;
        }
    }
}
int query(int a,int b)
{
    int c,i,p,q,LCA;
    a=First[a];
    b=First[b];
    if(a>b) swap(a,b);
    c=b-a;
    for(i=0,p=1;2*p<=c;i++,p<<=1);
    if(Nivel[RMQ[i][a]] < Nivel[RMQ[i][b-p+1]]) LCA=Euler[RMQ[i][a]];
    else LCA=Euler[RMQ[i][b-p+1]];
    return LCA;
}
int main()
{
    int i,a,b;
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    scanf("%d%d",&N,&M);
    for(i=2;i<=N;i++)
    {
        scanf("%d",&a);
        T[a].push_back(i);
    }
    DFS(1,0);
    Do_RMQ();
    for(;M;--M)
    {
        scanf("%d%d",&a,&b);
        printf("%d\n",query(a,b));
    }
    return 0;
}