Cod sursa(job #2374467)

Utilizator caesar2001Stoica Alexandru caesar2001 Data 7 martie 2019 18:53:02
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.95 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <utility>
#include <cmath>
#include <string>
#include <cstring>
#include <set>
#include <queue>
#include <map>
#include <stack>
#include <iomanip>
#define ll long long
#define lsb(x) (x & -x)

using namespace std;

ifstream in("lca.in");
ofstream out("lca.out");

void dfs(int node, vector<int> &h, vector<int> &euler, const vector<vector<int>> &g) {
    euler.push_back(node);
    for(auto it : g[node]) {
        h[it] = h[node] + 1;
        dfs(it, h, euler, g);

        euler.push_back(node);
    }
}

int main() {

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

    vector<int> euler;
    vector<int> h(n + 1, 0);
    h[1] = 1;
    dfs(1, h, euler, g);

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

    vector<vector<int>> rmq(lg[m] + 2, vector<int> (m, 0));
    vector<int> firstpos(n + 1, 0);
    for(int i = 0; i < m; i ++) {
        rmq[0][i] = euler[i];
        firstpos[euler[i]] = i;
    }
    for(int i = 1; i <= lg[m]; i ++) {
        int p = (1 << (i - 1));
        for(int j = 0; j + (1 << i) - 1 < m; j ++)
            if(h[rmq[i - 1][j]] < h[rmq[i - 1][j + p]])
                rmq[i][j] = rmq[i - 1][j];
            else
                rmq[i][j] = rmq[i - 1][j + p];
    }

    while(q --) {
        int a, b;
        in >> a >> b;
        a = firstpos[a];
        b = firstpos[b];

        if(a > b)
            swap(a, b);
        int len = b - a + 1;
        int ans;

        if(h[rmq[lg[len]][a]] < h[rmq[lg[len]][b - (1 << lg[len]) + 1]])
            ans = rmq[lg[len]][a];
        else
            ans = rmq[lg[len]][b - (1 << lg[len]) + 1];
        out << ans << "\n";
    }

    return 0;
}