Cod sursa(job #2634900)

Utilizator BAlexandruBorgovan Alexandru BAlexandru Data 12 iulie 2020 17:21:18
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.62 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];
pair < int, 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] = {d[e[i]], e[i]};

    for (int i=1; (1<<i) <= l; i++)
        for (int j=1; j + (1<<i) - 1 <= l; j++)
            if (rmq[j][i-1].first < rmq[j + (1<<(i-1))][i-1].first)
                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 (rmq[x][k].first < rmq[y - (1<<k) + 1][k].first)
        return rmq[x][k].second;
    else
        return rmq[y - (1<<k) + 1][k].second;
}

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;
}