Cod sursa(job #610492)

Utilizator elfusFlorin Chirica elfus Data 27 august 2011 15:02:34
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.84 kb
#include<stdio.h>
#include<vector>
#define NMAX 100100

using namespace std;

vector<int> L[NMAX];
int u, E[NMAX << 1], First[NMAX], Lev[NMAX];
int D[18][NMAX];

inline int log2(int X)
{
    int pow=0;
    while ((1<<pow) <= X)
        pow++;
    return pow - 1;
}

void DF(int nod, int nivel)
{
    vector<int> :: iterator it;
    E[++u] = nod;
    Lev[u] = nivel;
    for(it = L[nod].begin(); it != L[nod].end(); it ++)
        {
            DF(*it,nivel + 1);
            E[++u] = nod;
            Lev[u] = nivel;
        }
}

void RMQ()
{
    int i, j;
    for(i = 1; i <= u; i ++)
        D[0][i] = i;
    for(i = 1; i <= log2(u); i ++)
        for(j = 1; j <= u; j ++)
            {
                if(j + (1 << i) > u + 1)
                    break;
                if(Lev[D[i - 1][j]] > Lev[D[i - 1][j + (1 << (i - 1))]])
                    D[i][j] = D[i - 1][j + (1 << (i - 1))];
                else
                    D[i][j] = D[i - 1][j];
            }
}

void LCA(int x, int y)
{
    int X, Y, aux, lg, index;
    X = First[x];
    Y = First[y];
    if (X > Y)
        {
            aux = X;
            X = Y;
            Y = aux;
        }
    lg = log2(Y - X + 1);
    if(Lev[D[lg][X]] > Lev[D[lg][Y - (1 << lg) + 1]])
        index = D[lg][Y - (1 << lg) + 1];
    else
        index = D[lg][X];
    printf("%d\n", E[index]);
}

int main()
{
    int N, M, i, x, y;

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

    scanf("%d%d", &N, &M);
    for(i = 2; i <= N; i ++)
    {
        scanf("%d", &x);
        L[x].push_back(i);
    }

    DF(1, 0);
    for(i = 1; i <= u; i ++)
        if(!First[E[i]])
            First[E[i]] = i;

    RMQ();
    while(M --)
    {
        scanf("%d%d", &x, &y);
        LCA(x, y);
    }

    return 0;
}