Cod sursa(job #1439495)

Utilizator darkseekerBoaca Cosmin darkseeker Data 22 mai 2015 14:26:46
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.72 kb
#include <fstream>
#include <vector>
#include <iostream>
using namespace std;

const int MAX_N = 100005;
const int LOG_N = 19;

vector<int> G[MAX_N];
int first[MAX_N * 2], df[2 * MAX_N], lev[MAX_N * 2], nr = 0;
int RMQ[LOG_N][MAX_N * 2], P[2 * MAX_N];

void dfs(int node, int level) {
    df[++nr] = node;
    lev[nr] = level;
    first[node] = nr;

    for (auto v : G[node]) {
        dfs(v, level + 1);
        df[++nr] = node;
        lev[nr] = level;
    }
}

void rmq() {
    for (int i = 2; i <= nr; ++i)
        P[i] = P[i >> 1] + 1;

    for (int i = 1; i <= nr; ++i)
        RMQ[0][i] = i;

    for (int i = 1; ((1 << i) < nr); ++i) {
        for (int j = 1; j <= (nr - (1 << i)) + 1; ++j) {
            int p = 1 << (i - 1);
            if (lev[RMQ[i - 1][j]] < lev[RMQ[i - 1][j + p]]) {
                RMQ[i][j] = RMQ[i - 1][j];
            } else {
                RMQ[i][j] = RMQ[i - 1][j + p];
            }
        }
    }
}

int LCA(int x, int y) {
    int fx = first[x];
    int fy = first[y];

    if (fx > fy)
        swap(fx, fy);

    int diff = fy - fx + 1;
    int p = P[diff];

    if (lev[RMQ[p][fx]] < lev[RMQ[p][fy - (1 << p) + 1]]) {
        return df[RMQ[p][fx]];
    } else {
        return df[RMQ[p][fy - (1 << p) + 1]];
    }
}

int main() {
    ifstream fin("lca.in");
    ofstream fout("lca.out");
    int x, N, M, y;
    fin >> N >> M;

    for (int i = 1; i <= N - 1; ++i) {
        fin >> x;
        G[x].push_back(i + 1);
    }

    dfs(1, 0);
    rmq();

    /*
     *for (int i = 1; i <= nr; ++i) {
     *    cerr << df[i] << ' ' << lev[i] << endl;
     *}
     */

    for (int i = 0; i < M; ++i) {
        fin >> x >> y;
        fout << LCA(x, y) << '\n';
    }

    fin.close();
    fout.close();
    return 0;
}