Cod sursa(job #3338463)

Utilizator David_RadavoiRadavoi David Alexandru David_Radavoi Data 3 februarie 2026 15:42:50
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.12 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

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

#define NMAX 100000
#define LOG2 17

vector <int> arb[NMAX + 1];
vector <int> v;
int rmq[LOG2 + 1][NMAX + 1];
int l[NMAX + 1];
int r[NMAX + 1];
int nivel[NMAX + 1];
int lg[2 * NMAX + 1];
int t = 0;

void set_logs(){
    lg[0] = lg[1] = 0;
    for (int i = 2; i <= NMAX; i++){
        lg[i] = lg[i / 2] + 1;
    }
}

void dfs(int node){
    if (node == 1){
        nivel[node] = 1;
    }
    t++;
    l[node] = t;
    for (auto neighbour : arb[node]){
        v.push_back(node);
        nivel[neighbour] = nivel[node] + 1;
        dfs(neighbour);
    }
    v.push_back(node);
    t++;
    r[node] = t;
}

int e_stramos(int a, int b){
    return l[a] <= l[b] && r[b] <= r[a];
}

void range_node(int N){
    for (int i = 1; i < N; i++){
        rmq[0][i] = v[i];
    }
    for (int p = 1; p <= lg[N]; p++){
        for (int i = 1; i + (1 << p) - 1 < N; i++){
            int p1 = rmq[p - 1][i];
            int p2 = rmq[p - 1][i + (1 << (p - 1)) - 1];
            if (nivel[p1] < nivel[p2]){
                rmq[p][i] = p1;
            }
            else{
                rmq[p][i] = p2;
            }
        }
    }
}

int lca(int a, int b){
    if (nivel[a] < nivel[b]){
        return a;
    }
    return b;
}

int main()
{
    v.push_back(0);
    ios::sync_with_stdio(false);
    fin.tie(nullptr);
    fout.tie(nullptr);
    set_logs();
    int N, Q;
    fin >> N >> Q;
    for (int i = 1; i < N; i++){
        int x;
        fin >> x;
        arb[x].push_back(i + 1);
    }
    dfs(1);
    range_node(v.size());
    for (int i = 1; i <= Q; i++){
        int a, b;
        fin >> a >> b;
        int dist = lg[r[b] - l[a] + 1];
        if (l[a] <= r[b] && r[b] <= r[a]){
            fout << a << " ";
        }
        else if (l[b] <= l[a] && r[a] <= r[b]){
            fout << b << " ";
        }
        else{
            fout << lca(rmq[dist][l[a] - 1], rmq[dist][r[b] - (1 << dist) + 2]) << '\n';
        }
    }
    return 0;
}