Cod sursa(job #1689512)

Utilizator crysstyanIacob Paul Cristian crysstyan Data 14 aprilie 2016 12:21:19
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.57 kb
#include <fstream>
#include <vector>
#include <algorithm>
#include <cmath>
#define NMAX 400005
#define LMAX 22

using namespace std;

ifstream f("lca.in");
ofstream g("lca.out");

int i, n, nrquiz, euler[NMAX], lvl[NMAX], pos[NMAX], rmq[NMAX][LMAX], cnt = 0, x, j, st, dr;
vector < int > v[NMAX];
bool visited[NMAX];

void DFS(int node, int level)
{
    visited[node] = 1;
    cnt ++;
    euler[cnt] = node;
    lvl[cnt] = level;

    if (pos[node] == 0)
        pos[node] = cnt;

    for (auto & it : v[node])
        if (!visited[it])
    {
        DFS(it, level + 1);
        euler[++ cnt] = node;
        lvl[cnt] = level;
    }
}

int main()
{
    f >> n >> nrquiz;

    for (i = 2; i <= n; ++ i)
    {
        f >> x;
        v[x].push_back(i);
        v[i].push_back(x);
    }

    DFS(1, 1);

    for (i = 1; i <= cnt; ++ i)
        rmq[i][0] = i;

    for (j = 1; (1 << j) <= cnt; ++ j)
        for (i = 1; i + (1 << j) - 1 <= cnt; ++ i)
            if (lvl[rmq[i][j - 1]] < lvl[rmq[i + (1 << (j - 1))][j - 1]])
                rmq[i][j] = rmq[i][j - 1];
            else
                rmq[i][j] = rmq[i + (1 << (j - 1))][j - 1];

    for (; nrquiz; -- nrquiz)
    {
        f >> st >> dr;
        st = pos[st];
        dr = pos[dr];
        if (st > dr)
            swap(st, dr);

        int l = log2(dr - st + 1);

        if (lvl[rmq[st][l]] < lvl[rmq[dr - (1 << l) + 1][l]])
            g << euler[rmq[st][l]] << '\n';
        else
            g << euler[rmq[dr - (1 << l) + 1][l]] << '\n';
    }

    return 0;
}