Cod sursa(job #2447070)

Utilizator lflorin29Florin Laiu lflorin29 Data 11 august 2019 22:56:16
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.93 kb
#include <bits/stdc++.h>

using namespace std;

class Tree {
    vector< vector<int> >G;
    vector< vector<int> > jump;
    vector<int>First, Last, eulert, depth;
    int tmr, root;
  public:
    Tree(const int n = 0) : G(n), jump(20, vector<int>(n)), First(n), Last(n), eulert(n), depth(n) {
        tmr = 0;
        root = 0;
    }
    void AddEdge(int x, int y) {
        assert(0 <= x && x < (int)G.size());
        assert(0 <= y && y < (int)G.size());
        G[x].push_back(y);
        G[y].push_back(x);
    }

    void dfs(int u, int par, int dep) {
        depth[u] = dep;
        jump[0][u] = par;
        First[u] = tmr++;
        eulert.push_back(u);
        for(int i = 1; i < 20; ++i)
            if(jump[i - 1][u] != -1)
                jump[i][u] = jump[i - 1][jump[i - 1][u]];
        for(int v: G[u])
            if(v != par)
                dfs(v, u, dep + 1);
        eulert.push_back(u);
        Last[u] = tmr++;
    }
    int LCA(int a, int b) {
        if(depth[a] < depth[b])
            swap(a, b);
        for(int i = 19; i >= 0; --i)
            if(depth[a] - (1 << i) >= depth[b])
                a = jump[i][a];
        if(a == b)
            return a;
        for(int i = 19; i >= 0; --i)
            if(jump[i][a] != -1 && jump[i][b] != -1 && jump[i][a] != jump[i][b]) {
                a = jump[i][a];
                b = jump[i][b];
            }
        assert(a != root);
        return jump[0][a];
    }
    void Init() {
        dfs(root, -1, 0);
    }

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

    int n, q;
    cin >> n >> q;
    Tree tree(n);

    for(int i = 1; i < n; ++i) {
        int father;
        cin >> father;
        tree.AddEdge(father-1, i);
    }
    tree.Init();

    for(int i = 0; i < q; ++i) {
        int u, v;
        cin >> u >> v;
        cout << tree.LCA(u - 1, v - 1) + 1 << '\n';
    }
    return 0;
}