Cod sursa(job #933862)

Utilizator visanrVisan Radu visanr Data 30 martie 2013 13:05:55
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.62 kb
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;

#define Nmax 100010
#define pb push_back
#define forit(it, v) for(typeof((v).begin()) it = (v).begin(); it != (v).end(); ++ it)

int N, M, X, Y, Level[Nmax], Ancestor[20][Nmax];
vector<int> G[Nmax];

void DFS(int Node, int L, int Father)
{
    Level[Node] = L;
    Ancestor[0][Node] = Father;
    forit(it, G[Node])
        if(!Level[*it])
            DFS(*it, L + 1, Node);
}

void Build_Ancestors()
{
    for(int i = 1; (1 << i) <= N; ++ i)
        for(int j = 1; j <= N; ++ j)
            Ancestor[i][j] = Ancestor[i - 1][Ancestor[i - 1][j]];
}

int GetLCA(int X, int Y)
{
    if(Level[X] < Level[Y]) swap(X, Y);
    int StepX, StepY;
    for(StepX = 1; (1 << StepX) < Level[X]; StepX ++);
    for(StepY = 1; (1 << StepY) < Level[Y]; StepY ++);
    for(; StepX >= 0; StepX --)
        if(Level[X] - (1 << StepX) >= Level[Y])
            X = Ancestor[StepX][X];
    if(X == Y) return X;
    for(; StepY >= 0; StepY --)
        if(Ancestor[StepY][X] && Ancestor[StepY][X] != Ancestor[StepY][Y])
        {
            X = Ancestor[StepY][X];
            Y = Ancestor[StepY][Y];
        }
    return Ancestor[0][X];
}

int main()
{
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    int i;
    scanf("%i %i", &N, &M);
    for(i = 2; i <= N; ++ i)
    {
        scanf("%i", &X);
        G[X].pb(i);
    }
    DFS(1, 1, 0);
    Build_Ancestors();
    for(i = 1; i <= M; ++ i)
    {
        scanf("%i %i", &X, &Y);
        printf("%i\n", GetLCA(X, Y));
    }
    return 0;
}