Cod sursa(job #2782254)

Utilizator vmnechitaNechita Vlad-Mihai vmnechita Data 11 octombrie 2021 23:10:12
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.17 kb
#include <bits/stdc++.h>
#define pb push_back
#define NMAX 100005

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

struct A
{
    int nvl, nod;
};

vector < A > rmq[18];
vector < int > fii[NMAX], euler;
int nvl[NMAX], prim[NMAX];

void dfs(int k);

int main()
{
    int n, m, i, j, x, y, t[NMAX];

    fin >> n >> m;
    for(i = 2; i <= n; i++) fin >> t[i], fii[t[i]].pb(i);

    dfs(1);

    x = euler.size();
    y = log2(x);
    for(auto it:euler) rmq[0].pb({nvl[it], it});
    for(i = 1; i <= y; i++)
        for(j = 0; j < x - ((1<<i)-1); j++)
            if(rmq[i-1][j].nvl < rmq[i-1][j+(1<<(i-1))].nvl) rmq[i].pb(rmq[i-1][j]);
            else rmq[i].pb(rmq[i-1][j+(1<<(i-1))]);

    while(m--)
    {
        fin >> x >> y;
        x = prim[x], y = prim[y];
        if(x > y) swap(x, y);

        n = log2(y - x + 1);
        if(rmq[n][x].nvl < rmq[n][y-(1<<n)+1].nvl) fout << rmq[n][x].nod << '\n';
        else fout << rmq[n][y-(1<<n)+1].nod << '\n';
    }

    return 0;
}

void dfs(int k)
{
    euler.pb(k);
    prim[k] = euler.size() - 1;
    for(auto it:fii[k]) nvl[it] = nvl[k] + 1, dfs(it), euler.pb(k);
}