Cod sursa(job #2572682)

Utilizator caesar2001Stoica Alexandru caesar2001 Data 5 martie 2020 13:48:52
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.08 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <utility>
#include <cmath>
#include <string>
#include <cstring>
#include <stack>
#define ll long long

using namespace std;

struct LCA {
    vector<vector<int>> g;
    int n;
    vector<int> euler, h, firstpos; /// tb last pos??
    int m;
    vector<vector<int>> rmq;
    vector<int> lg;

    LCA(int _n, vector<vector<int>> &_g) {
        n = _n;
        g = _g;

        firstpos.resize(n + 1, 0);
        h.resize(n + 1, 0);
        h[1] = 1;
        dfs(1);

        m = euler.size();
        lg.resize(m + 1, 0);
        for(int i = 2; i <= m; i ++)
            lg[i] = 1 + lg[i >> 1];

        rmq.resize(lg[m] + 1, vector<int> (m, 0));
        for(int i = 0; i < m; i ++)
            rmq[0][i] = euler[i];
        for(int i = 1; i <= lg[m]; i ++)
            for(int j = 0; j + (1 << (i - 1)) < m; j ++) {
                int a = rmq[i - 1][j], b = rmq[i - 1][j + (1 << (i - 1))];
                if(h[a] < h[b])
                    rmq[i][j] = a;
                else
                    rmq[i][j] = b;
            }
    }

    int query(int a, int b) {
        a = firstpos[a];
        b = firstpos[b];
         if(a > b)
            swap(a, b);
        int dim = b - a + 1;
        int x = rmq[lg[dim]][a], y = rmq[lg[dim]][b - (1 << lg[dim]) + 1];
        if(h[x] > h[y])
            swap(x, y);
        return x;
    }

    void dfs(int node) {
        firstpos[node] = euler.size();
        euler.push_back(node);
        for(auto it : g[node]) {
            h[it] = h[node] + 1;
            dfs(it);
            euler.push_back(node);
        }
    }
};

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

    int n, m;
    in >> n >> m;
    vector<vector<int>> g(n + 1);
    for(int i = 2; i <= n; i ++) {
        int x;
        in >> x;
        g[x].push_back(i);
    }

    LCA lca(n, g);
    while(m --) {
        int x, y;
        in >> x >> y;
        out << lca.query(x, y) << "\n";
    }

    return 0;
}