Cod sursa(job #3346451)

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

using namespace std;

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

int n, m, k, euler[200005], niv[100001], first[100001], rmq[25][200005],
             log2[100001], pow2[25];

vector<int> adj[100001];

void DFS(int root){
    vector<int> it(n + 1, 0);
    vector<int> st;

    st.push_back(root);

    while (!st.empty()){
        int x = st.back();

        if (it[x] == 0){
            euler[++k] = x;
            first[x] = k;
        }

        if (it[x] < adj[x].size()){
            int y = adj[x][it[x]++];
            niv[y] = niv[x] + 1;
            st.push_back(y);
        }
        else{
            st.pop_back();
            if (!st.empty()){
                euler[++k] = st.back();
            }
        }
    }
}

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;
        adj[x].push_back(i);
    }

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