Cod sursa(job #2076022)

Utilizator dariusdariusMarian Darius dariusdarius Data 25 noiembrie 2017 23:05:10
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.63 kb
#include <algorithm>
#include <iostream>
#include <fstream>
using namespace std;
const int MAX_N = 100005;

vector<int> tree[MAX_N];
int level[MAX_N];
int first[MAX_N];
int k, euler[2 * MAX_N];
int lg[2 * MAX_N];
int rmq[20][2 * MAX_N];

void dfs(int node, int parent=0) {
    euler[++ k] = node;
    first[node] = k;
    level[node] = level[parent] + 1;
    for (auto son : tree[node]) {
        if (son != parent) {
            dfs(son, node);
            euler[++ k] = node;
        }
    }
}

int main() {
    ifstream cin("lca.in");
    ofstream cout("lca.out");
    int n, m;
    cin >> n >> m;
    for (int x, i = 2; i <= n; ++ i) {
        cin >> x;
        tree[x].push_back(i);
        tree[i].push_back(x);
    }
    dfs(1);
    for (int i = 2; i <= k; ++ i) {
        lg[i] = lg[i / 2] + 1;
    }
    for (int i = 1; i <= k; ++ i) {
        rmq[0][i] = i;
    }
    for (int i = 1; (1 << i) <= k; ++ i) {
        for (int j = 1; j + (1 << i) <= k; ++ j) {
            rmq[i][j] = rmq[i - 1][j];
            if (level[euler[rmq[i - 1][j + (1 << (i - 1))]]] < level[euler[rmq[i][j]]]) {
                rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
            }
        }
    }
    for (int x, y, i = 1; i <= m; ++ i) {
        cin >> x >> y;
        x = first[x];
        y = first[y];
        if (x > y) {
            swap(x, y);
        }
        int l = lg[y - x + 1];
        int index = rmq[l][x];
        if (level[euler[rmq[l][y - (1 << l) + 1]]] < level[euler[index]]) {
            index = rmq[l][y - (1 << l) + 1];
        }
        cout << euler[index] << "\n";
    }
    return 0;
}