Cod sursa(job #1378651)

Utilizator oprea1si2si3Oprea Sebastian oprea1si2si3 Data 6 martie 2015 13:28:29
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.99 kb
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;

ifstream in("lca.in");

const int kNMax = 100010, kLgMax = 18;
int n, m, prima_aparitie[kNMax], lg[2 * kNMax], rmq[kLgMax][2 * kNMax];
vector<int> G[kNMax];
vector<pair<int, int> > euler;

void Citire() {
    int x;
    in >> n >> m;
    for (int i = 2; i <= n; ++i) {
        in >> x;
        G[x].push_back(i);
    }
}

void Dfs(int nod, int nivel) {
    prima_aparitie[nod] = euler.size();
    euler.push_back(make_pair(nod, nivel));
    for (int i = 0; i < G[nod].size(); ++i) {
        int vecin = G[nod][i];
        Dfs(vecin, nivel + 1);
        euler.push_back(make_pair(nod, nivel));
    }
}

void ReprezentareEuler() {
    euler.push_back(make_pair(0, 0));
    Dfs(1, 0);
}

void PrecalculareLg() {
    n *= 2;
    for (int i = 2; i <= n; ++i)
        lg[i] = lg[i / 2] + 1;
}

void Rmq() {
    for (int i = 1; i <= n; ++i)
        rmq[0][i] = i;
    for (int i = 1; (1 << i) <= n; ++i)
        for (int j = 1; j + (1 << i) - 1 <= n; ++j)
            if (euler[rmq[i - 1][j]].second < euler[rmq[i - 1][j + (1 << (i - 1))]].second )
                rmq[i][j] = rmq[i - 1][j];
            else
                rmq[i][j] = rmq[i-1][j + (1 << (i - 1))];
}

void Initializare() {
    ReprezentareEuler();
    PrecalculareLg();
    Rmq();
}

int lca(int x, int y) {
    x = prima_aparitie[x];
    y = prima_aparitie[y];
    if (x > y)
        swap(x, y);
    int d = y - x + 1;
    if (euler[rmq[lg[d]][x]].second < euler[rmq[lg[d]][y - (1 << lg[d]) + 1]].second)
        return euler[rmq[lg[d]][x]].first;
    else
        return euler[rmq[lg[d]][y - (1 << lg[d]) + 1]].first;

}

void Query() {
    ofstream out ("lca.out");
    int x, y;
    while (m--) {
        in >> x >> y;
        out << lca(x, y) << '\n';
    }
    in.close();
    out.close();
}

void Solve() {
    Initializare();
    Query();
}

int main() {
    Citire();
    Solve();
    return 0;
}