Cod sursa(job #1898790)

Utilizator bt.panteaPantea Beniamin bt.pantea Data 2 martie 2017 11:48:47
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.55 kb
#include <iostream>
#include <fstream>
#include <vector>
#define NMAX 100005
#define LOGMAX 18
using namespace std;
ifstream f ("lca.in");
ofstream g ("lca.out");
vector <int> G[NMAX];
int LOG[NMAX], H[2 * NMAX], LVL[NMAX * 2], FIRST[NMAX], RMQ[NMAX * 2][LOGMAX], k, n, m; // k = Maxim dupa scrierea lui euler

void dfs(int nod, int lvl)
{
    H[++k] = nod;
    LVL[k] =lvl;
    FIRST[nod] = k;
    for (unsigned i = 0; i < G[nod].size(); i++)
    {
        dfs(G[nod][i], lvl + 1);
        H[++k] = nod;
        LVL[k] = lvl;
    }
}
void rmq()
{
    for (int i = 1; i <= k; i++)
        RMQ[i][0] = i;
    for (int i = 1; (1<<i) < k; i++)
    {
        for (int j = 1; j + (1 << i) <= k; j++)
        {
            int l = (1 << (i - 1));
            RMQ[j][i] = RMQ[j][i - 1];
            if (LVL[RMQ[j + l][i - 1]] < LVL[RMQ[j][i]])
                RMQ[j][i] = RMQ[j + l][i - 1];
        }
    }
}

int lca(int x, int y)
{
    int dif, l, sol, sh;
    int a = FIRST[x], b = FIRST[y];
    if (a > b)
        swap(a, b);
    dif = b - a + 1;
    l = LOG[dif];
    sol = RMQ[a][l];
    sh = dif - (1 << l);
    if (LVL[sol] > LVL[RMQ[a + sh][l]])
        sol = RMQ[a + sh][l];
    return H[sol];
}

int main()
{
    f>>n>>m;
    for (int x, i = 2; i <= n; i++)
    {
        f>>x;
        G[x].push_back(i);
    }
    dfs(1, 0);
    for (int i = 2; i <= k; i++)
        LOG[i] = LOG[i / 2] + 1;
    rmq();
    while (m--)
    {
        int x, y;
        f>>x>>y;
        g<<lca(x, y)<<'\n';
    }
    return 0;
}