Cod sursa(job #1253704)

Utilizator atatomirTatomir Alex atatomir Data 1 noiembrie 2014 18:03:38
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.45 kb
#include <iostream>
#include <cstdio>
#include <vector>

using namespace std;

#define maxN 100010
#define maxLog 20

long n,m,i,x,y,t;
long dp[maxLog+5][maxN];
vector<long> list[maxN];
long level[maxN];

void preProc(){
    for(long i=1;i<=maxLog;i++){
        for(long j=1;j<=n;j++){
            dp[i][j] = dp[i-1][dp[i-1][j]];
        }
    }
}

void DFS(long nod){
    for(long i=0;i<list[nod].size();i++){
        long newNod = list[nod][i];
        if(level[newNod]) continue;
        level[newNod] = level[nod] + 1;
        DFS(newNod);
    }
}

void Up(long& nod,long p){
    long i=0;
    while(p){
        if(p&1) nod = dp[i][nod];
        p >>= 1;
        i++;
    }
}

long LCA(long x,long y){
    long xx,yy;
    for(long i=maxLog;i>=0;i--){
        xx = dp[i][x]; yy = dp[i][y];
        if(xx == 0 || yy == 0) continue;
        if(xx != yy) x=xx,y=yy;
    }
    return dp[0][x];
}

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);

    scanf("%ld %ld",&n,&m);
    for(i=2;i<=n;i++) {
        scanf("%ld",&dp[0][i]);
        list[dp[0][i]].push_back(i);
    }

    preProc();
    DFS(1);

    for(i=1;i<=m;i++){
        scanf("%ld %ld",&x,&y);
        if(level[x] > level[y]) {t=x;x=y;y=t;}

        Up(y,level[y]-level[x]);
        if(x == y){
            printf("%ld\n",x);
        } else {
            printf("%ld\n",LCA(x,y));
        }
    }

    return 0;
}