Cod sursa(job #2155919)

Utilizator CammieCamelia Lazar Cammie Data 8 martie 2018 11:54:07
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.54 kb
#include <fstream>
#include <vector>

#define MAXN 100005

using namespace std;

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

vector <int> graph[MAXN];

int N, M, rmq[22][2 * MAXN], nn, viz[MAXN], log[MAXN], frst[MAXN];

inline void Read() {
    int x;

    fin >> N >> M;

    for (int i = 1; i < N; i++) {
        fin >> x;

        graph[x].push_back(i + 1);
    }
}

inline void DFS(int node) {
    rmq[0][++nn] = node; frst[node] = nn;
    for (auto x : graph[node]) {
        viz[x] = viz[node] + 1;
        DFS(x);
        rmq[0][++nn] = node;
    }
}

inline void RMQ() {
    for (int i = 2; i <= nn; i++)
        log[i] = log[i / 2] + 1;
    int mm = log[nn];

    for (int i = 1; i <= mm; i++) {
        for (int j = 1; j + (1 << (i - 1)) <= nn; j++) {
            if (viz[rmq[i - 1][j]] < viz[rmq[i - 1][j + (1 << (i - 1))]]) {
                rmq[i][j] = rmq[i - 1][j];
            }
            else {
                rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
            }
        }
    }
}

inline int Query(int a, int b) {
    if (a > b)
        swap(a, b);
    int m = log[b - a + 1];

    if (viz[rmq[m][a]] < viz[rmq[m][b - (1 << m) + 1]])
        return rmq[m][a];
    else
        return rmq[m][b - (1 << m) + 1];
}

inline void Solve() {
    int x, y;

    DFS(1);
    RMQ();

    while (M--) {
        fin >> x >> y;

        fout << Query(frst[x], frst[y]) << "\n";
    }
}

int main () {
    Read();
    Solve();

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