Cod sursa(job #1998735)

Utilizator savigunFeleaga Dragos-George savigun Data 8 iulie 2017 22:46:43
Problema Lowest Common Ancestor Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.65 kb
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;


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

const int MAXN = 1e5 + 5;
const int L = 1 << 18;
int n, m;
int dp[18][MAXN], level[MAXN], log[MAXN];
vector<int> g[MAXN];


void preprocess() {
    for (int k = 2; k <= 17; ++k) {
        for (int nod = 1; nod <= n; ++nod) {
            dp[k][nod] = dp[k-1][dp[k-1][nod]];
        }
    }
}

void set_log() {
    int next = 2;
    int lg = 0;
    for (int i = 1; i <= n; ++i) {
        if (i == next) {
            lg++;
            next *= 2;
        }
        log[i] = lg;
    }
}

void set_level(int x, int depth) {
    level[x] = depth;
    for (int i = 0; i < g[x].size(); ++i) {
        set_level(g[x][i], depth + 1);
    }
}

void levelize(int &x, int &y) {
    if (level[x] == level[y]) return;
    if (level[x] < level[y]) swap(x, y);
    int bit = log[x];
    while (bit) {
        if (level[dp[bit][x]] >= level[y]) {
            x = dp[bit][x];
        }
        bit--;
    }
}

int query(int x, int y) {
    levelize(x, y);

    if (x == y) return x;

    int bit = log[y];
    while (bit) {
        if (dp[bit][x] != dp[bit][y]) {
            x = dp[bit][x];
            y = dp[bit][y];
        }
        bit--;
    }

    return dp[1][x];
}


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

    preprocess();
    set_level(1, 1);
    set_log();

    for (int i = 1, x, y; i <= m; ++i) {
        in >> x >> y;
        out << query(x, y) << "\n";
    }

    return 0;
}