Cod sursa(job #2786114)

Utilizator VladTZYVlad Tiganila VladTZY Data 20 octombrie 2021 11:45:18
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.93 kb
#include <fstream>
#include <vector>

#define NMAX 100005
#define LOG 20

using namespace std;

ifstream f("lca.in");
ofstream g("lca.out");

int n, questions, root, x, y, step;
int nodeOrder[2 * NMAX], depthOrder[2 * NMAX];
int sparseTable[LOG][2 * NMAX];
int last[NMAX];
vector <int> v[NMAX];

void getLCA(int root, int depth) {
    step++;
    nodeOrder[step] = root;
    depthOrder[step] = depth;
    last[root] = step;

    for (auto neightbour : v[root]) {
        if (last[neightbour] == 0) {
            getLCA(neightbour, depth + 1);

            step++;
            nodeOrder[step] = root;
            depthOrder[step] = depth;
            last[root] = step;
        }
    }
}

void getSparseTable() {
    for (int i = 1; i <= step; i++) {
        sparseTable[0][i] = i;
    }

    for (int i = 1; (1 << i) <= step; i++) {

        for (int j = 1; j + (1 << i) - 1 <= step; j++) {
            int x = sparseTable[i - 1][j];
            int y = sparseTable[i - 1][j + (1 << (i - 1))];

            if (depthOrder[x] < depthOrder[y])
                sparseTable[i][j] = x;
            else
                sparseTable[i][j] = y;
        }
    }
}

int RMQ(int nodeX, int nodeY) {
    int x = min(last[nodeX], last[nodeY]);
    int y = max(last[nodeX], last[nodeY]);
    int length = y - x + 1;
    int log = 1;

    while ((1 << log) <= length) {
        log++;
    }
    log--;

    int firstPoz = sparseTable[log][x];
    int secondPoz = sparseTable[log][y - (1 << log) + 1];

    if (depthOrder[firstPoz] < depthOrder[secondPoz])
        return nodeOrder[firstPoz];
    return nodeOrder[secondPoz];
}

int main()
{
    f >> n >> questions;

    for (int i = 2; i <= n; i++) {
        f >> root;
        v[root].push_back(i);
    }

    getLCA(1, 1);
    getSparseTable();

    while (questions--) {
        f >> x >> y;
        g << RMQ(x, y) << "\n";
    }

    return 0;
}