Cod sursa(job #1673673)

Utilizator mihai.constantinConstantin Mihai mihai.constantin Data 3 aprilie 2016 23:52:10
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.19 kb
#include <iostream>
#include <cstdio>
using namespace std;

const int N_max = 100002;
const int M_max = 2000002;
const int Log = 18;

int urm[N_max];
int vf[N_max];
int lst[N_max];
int nr;

int level[N_max];
bool viz[N_max];

int tata[N_max];

int A[N_max][Log]; /* A[i][j] == AL 2 ^ j STRAMOS AL LUI i */

int N, Q;

void adauga(int x, int y)
{
    // ADAUGA IN LISTA LUI x PE y

    nr++;
    vf[nr] = y;
    urm[nr] = lst[x];
    lst[x] = nr;
}

void read()
{
    int i, j;

    scanf("%d %d", &N, &Q);

    for(i = 2; i <= N; i++)
    {
        scanf("%d", &tata[i]);

        adauga(tata[i], i);
    }

    /* CONSTRUIESC MATRICEA A */

    for(i = 1; i <= N; i++) A[i][0] = tata[i]; /* PRIMUL STRAMOS AL LUI i ESTE CHIAR TATALUI ACESTUIA */

    for(i = 1; i <= N; i++)
        for(j = 1; (1 << j) <= N; j++)
            if(A[i][j - 1]) A[i][j] = A[A[i][j - 1]][j - 1];
}

void dfs(int x)
{
    int p, y;

    viz[x] = true;

    // PARCURG VECINII y AI LUI x

    p = lst[x];

    while(p != 0)
    {
        y = vf[p];

        if(!viz[y])
        {
            level[y] = 1 + level[x];
            dfs(y);
        }

        p = urm[p];
    }
}

int lca(int p, int q)
{
    int j;

    if(level[p] < level[q]) swap(p, q);

    int lg1, lg2;

    for(lg1 = 0; (1 << lg1) <= level[p]; lg1++);
    lg1--;

    for(lg2 = 0; (1 << lg2) <= level[q]; lg2++);
    lg2--;

    for(j = lg1; j >= 0; j--)
        if(A[p][j] && level[A[p][j]] >= level[q]) /* EXISTA AL 2 ^ j STRAMOS AL LUI p && NIVELUL CELUI DE-AL 2 ^ j STRAMOS AL LUI p ESTE >= DECAT NIVELUL LUI q */
            p = A[p][j];

    if(p == q) return p;

    /* ACUM p SI q SUNT LA ACELASI NIVEL */

    for(j = lg2; j >= 0; j--)
        if(A[p][j] && A[p][j] != A[q][j]) /* EXISTA AL 2 ^ j STRAMOS AL LUI p SI NU MERG "PREA SUS" */
        {
            p = A[p][j];
            q = A[q][j];
        }

    /* SUNT LA UN NIVEL SUB DE lca(p, q) */

    return tata[p];
}

void query()
{
    int i, p, q;

    for(i = 1; i <= Q; i++)
    {
        scanf("%d %d", &p, &q);

        int ans = lca(p, q);

        printf("%d\n", ans);
    }
}

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

    read();
    dfs(1);
    query();

    return 0;
}