Cod sursa(job #2838310)

Utilizator toma_ariciuAriciu Toma toma_ariciu Data 23 ianuarie 2022 13:02:46
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.58 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

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

int n, q, e[400005], p[400005], depth[100005], poz[100005], ind, l2[400005];
int rmq[20][400005];
vector <int> G[100005];

void dfs(int nod)
{
    e[++ind] = nod;
    poz[nod] = ind;
    depth[nod] = depth[p[nod]] + 1;
    for(int vecin : G[nod])
    {
        if(vecin != p[nod])
        {
            dfs(vecin);
            e[++ind] = nod;
        }
    }
}

int main()
{
    fin >> n >> q;
    for(int i = 2; i <= n; i++)
    {
        fin >> p[i];
        G[p[i]].push_back(i);
    }
    dfs(1);
    for(int i = 2; i <= ind; i++)
        l2[i] = l2[i / 2] + 1;
    for(int i = 1; i <= ind; i++)
        rmq[0][i] = e[i];
    for(int j = 1; (1 << j) <= ind; j++)
    {
        for(int i = 1; i - 1 + (1 << j) <= ind; i++)
        {
            if(depth[rmq[j - 1][i]] < depth[rmq[j - 1][i + (1 << (j - 1))]])
                rmq[j][i] = rmq[j - 1][i];
            else
                rmq[j][i] = rmq[j - 1][i + (1 << (j - 1))];
        }
    }
    for(int i = 1; i <= q; i++)
    {
        int x, y;
        fin >> x >> y;
        int st, dr, log, ans;
        st = min(poz[x], poz[y]);
        dr = max(poz[x], poz[y]);
        log = l2[dr - st + 1];
        /// rmq[log][st], rmq[log][dr - log + 1]
        if(depth[rmq[log][st]] < depth[rmq[log][dr - (1 << log) + 1]])
            ans = rmq[log][st];
        else
            ans = rmq[log][dr - (1 << log) + 1];
        fout << ans << '\n';
    }
    return 0;
}