Cod sursa(job #2194426)

Utilizator CammieCamelia Lazar Cammie Data 13 aprilie 2018 11:42:01
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.61 kb
#include <fstream>
#include <vector>
#include <cstring>

#define inf 0x3f3f3f3f
#define MAXN 100005

using namespace std;

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

int rmq[19][MAXN * 3], frst[MAXN], depth[MAXN * 4], log[MAXN * 4];
int N, M, nn;

vector <int> graph[MAXN];

inline void Read() {
    int x;

    fin >> N >> M;

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

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

inline void DFS(int node) {
    rmq[0][++nn] = node; frst[node] = nn;

    for (auto x : graph[node]) {
        depth[x] = depth[node] + 1;
        DFS(x);
        rmq[0][++nn] = node;
    }
}

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

    int m = log[nn];

    for (int i = 1; i <= m; i++) {
        for (int j = 1; j + (1 << i) <= nn; j++) {
             if (depth[rmq[i - 1][j]] < depth[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 x, int y) {
    int a = frst[x], b = frst[y], m;

    if (a > b)
        swap(a, b);

    m = log[b - a + 1];

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

int main() {
    int x, y;

    Read();
    depth[1] = 1; DFS(1);
    RMQ();

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

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

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