Cod sursa(job #2908132)

Utilizator Albert_GAlbert G Albert_G Data 1 iunie 2022 16:42:08
Problema Lowest Common Ancestor Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.26 kb
#include <fstream>
#include <vector>

std::ifstream in("lca.in");
std::ofstream out("lca.out");

constexpr int N = 1e5+1, L = 17;
std::vector<int> g[N];
int ancestor[L][N], ti[N], to[N], currTime, emax[N]; // ancestor[e][i] -> e'th ancestor of node i

void dfs(int i){
    ti[i] = ++currTime;
    for(auto child : g[i])
        dfs(child);
    to[i] = ++currTime;
}

bool is_ancestor(int x, int y){ // x is ancestor of y
    return (ti[x] <= ti[y] && to[x] >= to[y]);
}

int lca(int x, int y){
    if(is_ancestor(x, y))
        return x;
    for(int e=emax[x]; e>=0; --e){
        if(ancestor[e][x] != 0 && !is_ancestor(ancestor[e][x], y))
            x = ancestor[e][x];
    }
    return ancestor[0][x];
}

int main(){
    int n, q;
    in >> n >> q;
    for(int i=2; i<=n; ++i){
        in >> ancestor[0][i];
        g[ancestor[0][i]].push_back(i);
    }
    for(int e=1; (1 << e) <= n; ++e){
        for(int i=1; i<=n; ++i){
            ancestor[e][i] = ancestor[e-1][ancestor[0][i]];
            if(ancestor[e][i] > 0)
                emax[i] = e;
        }
    }
    dfs(1);
    for(int i=0; i<q; ++i){
        int x, y;
        in >> x >> y;
        out << lca(x, y) << '\n';
    }
    in.close();
    out.close();
    return 0;
}