Cod sursa(job #1439487)

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

const int MAX_N = 100000;
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];

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 = 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, p = 0;

    while ((1 << p) <= diff) {
        p++;
    }

    p--;

    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) << endl;
    }

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