Cod sursa(job #2858196)

Utilizator MR0L3eXMaracine Constantin Razvan MR0L3eX Data 27 februarie 2022 10:40:01
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.52 kb
#include "bits/stdc++.h"
 
using namespace std;
 
using ld = long double;
using ll = long long;
using ull = unsigned long long;
 
#if defined(ONPC)
#include "bits/debug.h"
#endif
 
vector<vector<int>> adj, anc;
vector<bool> vis;
vector<int> depth;
int LOG = 1;
 
void dfs(int node = 0) {
    for (int u : adj[node]) {
        anc[u][0] = node;
        for (int bit = 1; bit < LOG; ++bit) {
            anc[u][bit] = anc[anc[u][bit - 1]][bit - 1];
        }
        depth[u] = depth[node] + 1;
        dfs(u);
    }
}
   
int lca(int a, int b) {
    if (depth[a] > depth[b]) {
        swap(a, b);
    }
    int dist = depth[b] - depth[a];
    for (int k = LOG - 1; k >= 0; --k) {
        if (dist & (1 << k)) {
            b = anc[b][k];
        }
    }
    if (a == b) {
        return a;
    }
    for (int k = LOG - 1; k >= 0; --k) {
        if (anc[a][k] != anc[b][k]) {
            a = anc[a][k];
            b = anc[b][k];
        }
    }
    return anc[a][0];
}
 
int32_t main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    
    int n, Q;
    cin >> n >> Q;
    
    while ((1 << LOG) <= n) ++LOG;
    
    anc.resize(n, vector<int>(LOG));
    adj.resize(n);
    vis.resize(n);
    depth.resize(n);
    
    for (int i = 1; i < n; ++i) {
        int x;
        cin >> x;
        --x;
        adj[x].push_back(i);
    }
    
    dfs();
    
    while (Q--) {
        int a, b;
        cin >> a >> b;
        --a, --b;
        cout << lca(a, b) + 1 << "\n";
    }
}