Cod sursa(job #2426669)

Utilizator retrogradLucian Bicsi retrograd Data 28 mai 2019 23:55:25
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.45 kb
#include <bits/stdc++.h>

using namespace std;

int main() {
    ifstream cin("lca.in");
    ofstream cout("lca.out");

    int n, q; cin >> n >> q;
    vector<vector<int>> graph(n);
    for (int i = 1; i < n; ++i) {
        int par; cin >> par; --par;
        graph[par].push_back(i);
    }

    vector<vector<int>> link(20, vector<int>(n, -1));
    vector<int> depth(n, 0);

    vector<int> order = {0};
    for (int i = 0; i < n; ++i) {
        int node = order[i];
        for (auto vec : graph[node]) {
            depth[vec] = 1 + depth[node];
            link[0][vec] = node;
            for (int i = 1; i < 20; ++i) {
                int anc = link[i - 1][vec];
                if (anc != -1) 
                    link[i][vec] = link[i - 1][anc];
            }
            order.push_back(vec);
        }
    }
    
    auto lca = [&](int a, int b) {
        if (depth[a] < depth[b]) swap(a, b);
        
        int d = depth[a] - depth[b];
        for (int i = 0; d; ++i) {
            if (d % 2)
                a = link[i][a];
            d /= 2;
        }
        assert(depth[a] == depth[b]);
        
        if (a == b) return a;
    
        for (int i = 19; i >= 0; --i) 
            if (link[i][a] != link[i][b])
                a = link[i][a], b = link[i][b];
    
        assert(link[0][a] == link[0][b]);
        return link[0][a];
    };

    while (q--) {
        int a, b; cin >> a >> b; --a; --b;
        cout << lca(a, b) + 1 << '\n';
    }
    return 0;
}