Cod sursa(job #2397906)

Utilizator NineshadowCarapcea Antonio Nineshadow Data 4 aprilie 2019 21:17:13
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.25 kb
#include <bits/stdc++.h>
#define MAXN 100005
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
int n, m, parent[MAXN], lev[MAXN], v[MAXN], h, r;
int t_bloc[MAXN];

vector<int> fii[MAXN];


void h_dfs(int nod, int level) {
    v[nod] = 1;
    lev[nod] = level;
    if(level > h) {
        h = level;
    }
    for(int i : fii[nod]) {
        if(v[i] == 0) {
            h_dfs(i, level + 1);
        }
    }
}

void dfs(int nod, int t_b) {
    t_bloc[nod] = t_b;
    if(lev[nod] % r == 0) {
        t_b = nod;
    }
    for(int i : fii[nod]) {
        dfs(i, t_b);
    }
}

int lca(int x, int y) {
    while(t_bloc[x] != t_bloc[y]) {
        if(lev[x] > lev[y]) {
            x = t_bloc[x];
        } else {
            y = t_bloc[y];
        }
    }
    while(x != y) {
        if(lev[x] > lev[y]) {
            x = parent[x];
        } else {
            y = parent[y];
        }
    }
    return x;
}

int main() {
    in >> n >> m;
    for(int i = 1; i < n; ++i) {
        int t;
        in >> t;
        parent[i + 1] = t;
        fii[t].push_back(i + 1);
    }

    // Find h
    h_dfs(1, 1);
    r = sqrt(h);

    // Calc tatii blocurilor
    dfs(1, 1);

    while(m--) {
        int a, b;
        in >> a >> b;
        out << lca(a, b) << "\n";
    }
}