Cod sursa(job #1563612)

Utilizator livliviLivia Magureanu livlivi Data 6 ianuarie 2016 13:05:29
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.45 kb
#include<cstdio>
#define N 100000
#define P 17
using namespace std;

int stra[P][N+1];
int nivel[N+1];

void afla(int i){
    if (nivel[i]==0){
        afla(stra[0][i]);
        nivel[i]=nivel[stra[0][i]]+1;
    }
}

int adu(int x,int niv){
    int p;

    for(p=16;p>=0;p--)
        if (nivel[stra[p][x]]>=niv) x=stra[p][x];

    return x;
}

int lca(int x,int y){
    if (nivel[x]>nivel[y]) x=adu(x,nivel[y]);
    else y=adu(y,nivel[x]);

    int p;
    for(p=16;p>=0;p--)
        if (stra[p][x]!=stra[p][y]){
            x=stra[p][x];
            y=stra[p][y];
        }

    if (x!=y) x=stra[0][x];

    return x;
}


char s[7*N+5];
int k;

bool isDigit(char c){
    if (c>='0' &&c<='9') return true;
    return false;
}

int get(){
    while(s[k]==' ') k++;

    if (s[k]==0){
        gets(s);
        k=0;
    }

    int nr=0;
    while(isDigit(s[k])){
        nr=nr*10+s[k]-'0';
        k++;
    }

    return nr;
}


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

    //scanf ("%d%d",&n,&m);
    n=get();
    m=get();

    for(i=2;i<=n;i++)
        stra[0][i]=get();
        //scanf ("%d",&stra[0][i]);

    for(i=1;i<P;i++)
        for(j=2;j<=n;j++)
            stra[i][j]=stra[i-1][stra[i-1][j]];

    nivel[1]=1;
    for(i=2;i<=n;i++)
        if (nivel[i]==0) afla(i);

    for(i=1;i<=m;i++){
        //scanf ("%d%d",&x,&y);
        x=get();
        y=get();
        printf ("%d\n",lca(x,y));
    }

    return 0;
}