Cod sursa(job #1693602)

Utilizator Theodor1000Cristea Theodor Stefan Theodor1000 Data 23 aprilie 2016 15:39:14
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.56 kb
#include <cstdio>
#include <algorithm>
#include <vector>

using namespace std;

vector <int> son[100010];
int p2[200010], rmq[18][200010], poz[100010], nivel[18][200010], k;

inline void dfs (int nod, int lvl)
{
    rmq[0][++k] = lvl;
    nivel[0][k] = nod;
    poz[nod] = k;

    for (int i = 0; i < son[nod].size (); ++i)
    {
        dfs (son[nod][i], lvl + 1);

        rmq[0][++k] = lvl;
        nivel[0][k] = nod;
    }
}

inline int lca (int x, int y)
{
    x = poz[x];
    y = poz[y];

    if (x > y) swap (x, y);

    int k = p2[y - x + 1];

    int a = rmq[k][x], p1 = nivel[k][x];
    int b = rmq[k][y - (1 << k) + 1], p2 = nivel[k][y - (1 << k) + 1];

    return ((a < b) ? p1 : p2);
}

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

    int n, m;
    scanf ("%d %d", &n, &m);

    for (int i = 2; i <= n; ++i)
    {
        int x;
        scanf ("%d", &x);

        son[x].push_back (i);
    }

    dfs (1, 1);

    for (int i = 2; i <= k; ++i)
        p2[i] = p2[i >> 1] + 1;

    for (int i = 1; (1 << i) <= k; ++i)
        for (int j = 1; j + (1 << i) - 1 <= k; ++j)
        {
            int a = rmq[i - 1][j], p1 = nivel[i - 1][j];
            int b = rmq[i - 1][j + (1 << (i - 1))], p2 = nivel[i - 1][j + (1 << (i - 1))];

            rmq[i][j] = min (a, b);
            nivel[i][j] = ((a < b) ? p1 : p2);
        }

    for (; m; --m)
    {
        int x, y;
        scanf ("%d %d", &x ,&y);

        printf ("%d\n", lca (x, y));
    }

    return 0;
}