Cod sursa(job #1807866)

Utilizator VictoriaNevTascau Victoria VictoriaNev Data 16 noiembrie 2016 23:26:39
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.43 kb
#include <fstream>
#include <vector>
using namespace std;
const int kMaxN = 100005;
vector<int> vertex[kMaxN];
int first[kMaxN], rmq[20][2*kMaxN], deep[kMaxN];
int nr_rmq;

void dfs(int nod)
{
    rmq[0][++nr_rmq] = nod;
    first[nod] = nr_rmq;
    for (int i = 0; i < vertex[nod].size(); ++i)
    {
        int oth = vertex[nod][i];
        deep[oth] = deep[nod] + 1;
        dfs(oth);
        rmq[0][++nr_rmq] = nod;
    }
}

int lca(int x, int y)
{
    x = first[x];
    y = first[y];
    if (x > y)
        swap(x, y);
    if (x == y)
        return x;
    int d = 0;
    while ((1 << d) < (y - x + 1))
        ++d;
    --d;
    if (deep[rmq[d][x]] < deep[rmq[d][y - (1 << d) + 1]])
        return rmq[d][x];
    return rmq[d][y - (1 << d) + 1];
}

void make_rmq()
{
    for (int l = 1; (1 << l) <= nr_rmq; ++l)
        for (int st = 1; st + (1 << l) <= nr_rmq; ++st)
        {
            int dr = st + (1 << (l - 1));
            if (deep[rmq[l - 1][st]] < deep[rmq[l - 1][dr]])
                rmq[l][st] = rmq[l - 1][st];
            else
                rmq[l][st] = rmq[l - 1][dr];
        }
}

int main()
{

    ifstream in("lca.in");
    ofstream out("lca.out");
    int n, m;
    in >> n >> m;
    for (int i = 2; i <= n; ++i)
    {
        int x;
        in >> x;
        vertex[x].push_back(i);
    }
    dfs(1);
    make_rmq();
    while (m--)
    {
        int x, y;
        in >> x >> y;
        out << lca(x, y) << '\n';
    }
    return 0;
}