Cod sursa(job #2307602)

Utilizator caesar2001Stoica Alexandru caesar2001 Data 25 decembrie 2018 00:16:45
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.81 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <climits>

using namespace std;

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

const int NMAX = 100000;

vector<int> g[NMAX + 5];
vector<int> euler;
int firstpos[NMAX + 5];
vector<int> h(NMAX + 5, INT_MAX);

void dfs(int node, int dad) {
    firstpos[node] = euler.size();
    euler.push_back(node);

    for(auto it : g[node])
        if(it != dad) {
            h[it] = h[node] + 1;
            dfs(it, node);
            euler.push_back(node);
        }
}

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

    h[1] = 0;
    dfs(1, 0);
    int sz = euler.size();

    vector<int> lg(sz + 1, 0);
    for(int i = 2; i <= sz; i ++)
        lg[i] = lg[i >> 1] + 1;

    vector<vector<int>> rmq(lg[sz] + 1, vector<int> (2 * sz + 1, NMAX + 3));
    for(int i = 0; i < sz; i ++)
        rmq[0][i] = euler[i];

    for(int i = 1; i <= lg[sz]; i ++) {
        for(int j = 0; j < sz && ((1 << i) + j) < sz; j ++) {
            if(h[rmq[i - 1][j]] < h[rmq[i - 1][j + (1 << (i - 1))]])
                rmq[i][j] = rmq[i - 1][j];
            else
                rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
        }
    }

    for(int i = 1; i <= m; i ++) {
        int x, y;
        in >> x >> y;
        if(firstpos[x] > firstpos[y])
            swap(x, y);

        int p = lg[firstpos[y] - firstpos[x]];
        int ans;
        if(h[rmq[p][firstpos[x]]] < h[rmq[p][firstpos[y] - (1 << p) + 1]])
            ans = rmq[p][firstpos[x]];
        else
            ans = rmq[p][firstpos[y] - (1 << p) + 1];
        out << ans << "\n";
    }

    return 0;
}