Cod sursa(job #2887070)

Utilizator toma_ariciuAriciu Toma toma_ariciu Data 8 aprilie 2022 19:29:37
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.54 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

const string filename = "lca";
ifstream fin(filename + ".in");
ofstream fout(filename + ".out");

const int maxN = 100005, inf = 0x3f3f3f3f;
int n, q, depth[maxN], euler[2 * maxN], poz_euler[maxN], ind_euler, log2[2 * maxN];
int rmq[20][2 * maxN];
vector <int> G[maxN];

void dfs(int nod, int d)
{
    euler[++ind_euler] = nod;
    poz_euler[nod] = ind_euler;
    depth[nod] = d;
    for(int vecin : G[nod])
    {
        dfs(vecin, d + 1);
        euler[++ind_euler] = nod;
    }
}

bool cmp(int a, int b)
{
    return (depth[a] < depth[b]);
}

int main()
{
    fin >> n >> q;
    for(int x, i = 2; i <= n; i++)
    {
        fin >> x;
        G[x].push_back(i);
    }
    dfs(1, 1);
    depth[0] = inf;
    for(int i = 2; i <= ind_euler; i++)
        log2[i] = log2[i / 2] + 1;
    for(int i = 1; i <= ind_euler; i++)
        rmq[0][i] = euler[i];
    for(int j = 1; (1 << j) <= ind_euler; j++)
        for(int i = 1; i + (1 << (j - 1)) - 1 <= ind_euler; i++)
            rmq[j][i] = min(rmq[j - 1][i], rmq[j - 1][i + (1 << (j - 1))], cmp);
    for(int i = 1; i <= q; i++)
    {
        int x, y, st, dr, log;
        fin >> x >> y;
        st = poz_euler[x];
        dr = poz_euler[y];
        if(st > dr)
            swap(st, dr);
        log = log2[dr - st + 1];
        int ans = min(rmq[log][st], rmq[log][dr - (1 << log) + 1], cmp);
        fout << ans << '\n';
    }
    return 0;
}