Cod sursa(job #3346445)

Utilizator mihai_moldovan11555mihai moldovan mihai_moldovan11555 Data 13 martie 2026 16:40:49
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.75 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

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

int n, m, k, euler[100001], niv[100001], first[100001], rmq[12][100001],
             log2[100001], pow2[20];

vector<int> adj[100001];

void DFS(int x){
    euler[++k] = x;
    first[x] = k;
    rmq[0][x] = x;

    for (const auto& y: adj[x]){
        niv[y] = niv[x] + 1;
        DFS(y);
        euler[++k] = x;
    }
}

void construct_rmq(){
    pow2[0] = 1;
    for (int i = 1; i <= k; i ++){
        if (i > 1)
            log2[i] = log2[i >> 1] + 1;

        if (i <= 20)
            pow2[i] = pow2[i - 1] << 1;
    }

    ///minimul dintre doua pozitii din parcurgerea euler a arborelui

    for (int i = 1; i <= k; i ++)
        rmq[0][i] = i;

    for (int j = 1; pow2[j] <= k; j ++)
        for (int i = 1; i + pow2[j] - 1 <= k; i ++){
            int u = rmq[j - 1][i], v = rmq[j - 1][i + pow2[j - 1]];

            if (niv[euler[u]] < niv[euler[v]])
                rmq[j][i] = u;
            else
                rmq[j][i] = v;
        }
}

int query(int l, int r){
    if (l > r)
        swap (l, r);
    int d = r - l + 1;
    int j = log2[d];
    int pl = rmq[j][l], pr = rmq[j][r - pow2[j] + 1];

    if (niv[euler[pl]] < niv[euler[pr]])
        return pl;
    else
        return pr;
}

int lca(int x, int y){
    int pos = query(first[x], first[y]);
    return euler[pos];
}

int main()
{
    fin >> n >> m;
    for (int i = 2, x; i <= n; i ++){
        fin >> x;
        T[i] = x;
        adj[x].push_back(i);
    }

    DFS(1);
    construct_rmq();
    while (m --){
        int x, y;
        fin >> x >> y;
        fout << lca(x, y) << '\n';
    }
}