Cod sursa(job #2570639)

Utilizator PopoviciRobertPopovici Robert PopoviciRobert Data 4 martie 2020 18:12:50
Problema Lowest Common Ancestor Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.56 kb
#include <bits/stdc++.h>
#define lsb(x) (x & (-x))
#define ll long long
#define ull unsigned long long
#define uint unsigned int


using namespace std;

vector <vector <int>> g, rmq;
vector <int> first, lvl, lg;
int sz;

void dfs(int nod) {
    rmq[++sz][0] = nod;
    first[nod] = sz;
    for(auto it : g[nod]) {
        lvl[it] = lvl[nod] + 1;
        dfs(it);
        rmq[++sz][0] = nod;
    }
}

inline int get(int x, int y) {
    x = first[x], y = first[y];
    if(x > y) swap(x, y);
    int bit = lg[y - x + 1];
    int a = rmq[x][bit], b = rmq[y - (1 << bit) + 1][bit];
    return (lvl[a] < lvl[b] ? a : b);
}

int main() {
#ifdef HOME
    ifstream cin("A.in");
    ofstream cout("A.out");
#endif
    ifstream cin("lca.in");
    ofstream cout("lca.out");
    int i, n, m;
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    cin >> n >> m;
    g.resize(n + 1);
    for(i = 2; i <= n; i++) {
        int par; cin >> par;
        g[par].push_back(i);
    }
    rmq.resize(2 * n + 1, vector <int>(20));
    first.resize(n + 1), lvl.resize(n + 1);
    dfs(1);
    lg.resize(2 * n + 1);
    for(i = 2; i <= n; i++) {
        lg[i] = lg[i >> 1] + 1;
    }
    for(int bit = 1; (1 << bit) <= sz; bit++) {
        for(i = 1; i + (1 << bit) <= sz + 1; i++) {
            int a = rmq[i][bit - 1], b = rmq[i + (1 << (bit - 1))][bit - 1];
            rmq[i][bit] = (lvl[a] < lvl[b] ? a : b);
        }
    }
    while(m--) {
        int x, y; cin >> x >> y;
        cout << get(x, y) << "\n";
    }

    return 0;
}