Cod sursa(job #2858545)

Utilizator VladTZYVlad Tiganila VladTZY Data 27 februarie 2022 20:10:14
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.83 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, x, y;
int first[NMAX];
int sparseTable[LOG][2 * NMAX];
vector <int> neighbours[NMAX];
vector <pair <int, int> > euler;

void DFS(int node, int level) {

    euler.push_back({node, level});

    if (!first[node])
        first[node] = euler.size() - 1;

    for (auto neighbour : neighbours[node]) {

        DFS(neighbour, level + 1);
        euler.push_back({node, level});
    }
}

void getSparseTable() {

    for (int i = 0; i < euler.size(); i++)
        sparseTable[0][i] = i;

    for (int i = 1; (1 << i) <= euler.size(); i++) {

        for(int j = 0; j <= euler.size() - (1 << i); j++) {
            int x = sparseTable[i - 1][j];
            int y = sparseTable[i - 1][j + (1 << (i - 1))];

            if (euler[x].second > euler[y].second)
                sparseTable[i][j] = y;
            else
                sparseTable[i][j] = x;
        }
    }
}

int getRmq(int x, int y) {
    int firstPoz = min(first[x], first[y]);
    int lastPoz = max(first[x], first[y]);
    int length = lastPoz - firstPoz + 1;
    int log = 0;

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

    int firstVal = sparseTable[log][firstPoz];
    int secondVal = sparseTable[log][lastPoz - (1 << log) + 1];

    if (euler[firstVal].second < euler[secondVal].second)
        return euler[firstVal].first;

    return euler[secondVal].first;
}


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

    for (int i = 2; i <= n; i++) {
        f >> x;

        neighbours[x].push_back(i);
    }

    DFS(1, 1);
    getSparseTable();

    while (questions--) {
        f >> x >> y;

        g << getRmq(x, y) << "\n";
    }

    return 0;
}