Cod sursa(job #3360332)

Utilizator torjexPetrescu Andrei torjex Data 12 iulie 2026 15:39:26
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.48 kb
#include <fstream>
#include <vector>

using namespace std;

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

const int NMAX = 250002;
const int LOG = 20;
int binLift[NMAX][LOG];
vector<int> adj[NMAX];
int in[NMAX];
int out[NMAX];
int n,q;

void buildBL() {
    for (int i=1;(1<<i)<=n;i++) {
        for (int node=1;node<=n;node++) {
            binLift[node][i] = binLift[binLift[node][i-1]][i-1];
        }
    }
}

int GetKthAncestor(int node,int k) {
    for (int i=0;(1<<i)<=k;i++) {
        if (k & (1<<i)) {
            node = binLift[node][i];
        }
    }
    return node;
}

int time=0;
void dfs(int node) {
    in[node] = ++time;
    for (auto child : adj[node]) {
        dfs(child);
    }
    out[node] = time;
}

bool isAncestor(int a,int b) {
    if (a==0) return true;
    return (in[a] <= in[b] && out[a] >= out[b]);
}

int lca(int a,int b) {
    int st=0,dr=n;
    int lca = a;
    while (st<=dr) {
        int mij = (st+dr)/2;
        int anc = GetKthAncestor(a,mij);
        if (isAncestor(anc,b)) {
            lca = anc;
            dr = mij-1;
        } else {
            st = mij+1;
        }
    }
    return lca;
}

int main()
{
    int a;
    fin>>n>>q;
    for (int i=2;i<=n;i++) {
        fin>>a;
        adj[a].push_back(i);
        binLift[i][0] = a;
    }
    dfs(1);
    buildBL();
    int x,y;
    for (int i=0;i<q;i++) {
        fin>>x>>y;
        fout<<lca(x,y)<<'\n';
    }
    return 0;
}