Cod sursa(job #2908320)

Utilizator CaptnBananaPetcu Tudor CaptnBanana Data 2 iunie 2022 20:28:53
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.24 kb
#include <fstream>
#include <vector>

using namespace std;

ifstream f("lca.in");
ofstream g("lca.out");

const int N = 1e5 + 1, LOG = 17;
int n, m, x, y, timp;
int t[LOG][N], ti[N], to[N], emax[N]; // t[e][i] = al 2^e-lea stramos as lui i
vector<int> fii[N];

void dfs(int x){
    ti[x] = ++timp; // timp de intrare
    for(int y: fii[x])
        dfs(y);

    to[x] = ++timp; // timp de iesire
}

// daca x este stramos al lui y;
inline bool este_stramos(int x, int y){
    return ti[x] <= ti[y] && to[x] >= to[y];
}

int lca(int x, int y){
    if(este_stramos(x, y))
        return x;

    for(int e = emax[x]; e >= 0; e--){
        if(t[e][x] && !este_stramos(t[e][x], y))
            x = t[e][x];
    }

    return t[0][x];
}

int main(){
    f >> n >> m;
    for(int i = 2; i <= n; i++){
        f >> t[0][i];
        fii[t[0][i]].push_back(i);
    }

    for(int e = 1; (1 << e) <= n; e++){
        for(int i = 1; i <= n; i++){
            t[e][i] = t[e - 1][t[e - 1][i]];
            if(t[e][i])
                emax[i] = e; // cel mai indepartat stramos log2
        }
    }

    dfs(1);
    while(m--){
        f >> x >> y;
        g << lca(x, y) << '\n';
    }

    f.close();
    g.close();
}