Cod sursa(job #2634904)

Utilizator BAlexandruBorgovan Alexandru BAlexandru Data 12 iulie 2020 17:30:30
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.57 kb
#include <fstream>
#include <vector>

using namespace std;

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

int n, m;
int d[100001], poz[100001], lg[200000];
int rmq[200000][18];

vector < int > e;
vector < int > v[100001];

void dfs(int nod)
{
    for (auto it : v[nod])
    {
        d[it] = d[nod] + 1;
        dfs(it);
    }
}

void eulerTour(int nod)
{
    e.push_back(nod);
    poz[nod] = e.size() - 1;

    for (auto it : v[nod])
    {
        eulerTour(it);
        e.push_back(nod);
        poz[nod] = e.size() - 1;
    }
}

void preprocess()
{
    int l = e.size() - 1;

    for (int i=1; i<=l; i++)
        rmq[i][0] = e[i];

    for (int i=1; (1<<i) <= l; i++)
        for (int j=1; j + (1<<i) - 1 <= l; j++)
            if (d[rmq[j][i-1]] < d[rmq[j + (1<<(i-1))][i-1]])
                rmq[j][i] = rmq[j][i-1];
            else
                rmq[j][i] = rmq[j + (1<<(i-1))][i-1];

    for (int i=2; i<=l; i++)
        lg[i] = lg[i/2] + 1;
}

int lca(int x, int y)
{
    if (poz[x] > poz[y])
        swap(x, y);
    x = poz[x];
    y = poz[y];

    int k = lg[y - x + 1];
    if (d[rmq[x][k]] < d[rmq[y - (1<<k) + 1][k]])
        return rmq[x][k];
    else
        return rmq[y - (1<<k) + 1][k];
}

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

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

    d[1] = 1; dfs(1);

    e.push_back(0), eulerTour(1);

    preprocess();

    while (m--)
    {
        int x, y; f >> x >> y;
        g << lca(x, y) << "\n";
    }

    return 0;
}