Cod sursa(job #2973348)

Utilizator victor_gabrielVictor Tene victor_gabriel Data 31 ianuarie 2023 20:07:59
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.55 kb
#include <fstream>
#include <vector>

using namespace std;

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

const int DIM = 100010;
const int MAX_LOG = 20;

int n, m, node1, node2;
int father[DIM], ancestors[MAX_LOG][DIM], level[DIM];
int first[DIM], last[DIM], currPos;
vector<int> l[DIM];

void dfs(int node, int lvl) {
    level[node] = lvl;
    first[node] = ++currPos;
    for (auto adjNode : l[node])
        dfs(adjNode, lvl + 1);
    last[node] = ++currPos;
}

void calculateAncestors() {
    for (int node = 1; node <= n; node++)
        ancestors[0][node] = father[node];
    for (int exp = 1; exp < MAX_LOG; exp++)
        for (int node = 1; node <= n; node++)
            ancestors[exp][node] = ancestors[exp - 1][ancestors[exp - 1][node]];
}

inline bool isAncestor(int node1, int node2) {
    return first[node1] <= first[node2] && last[node2] <= last[node1];
}

inline int getLCA(int node1, int node2) {
    if (isAncestor(node1, node2))
        return node1;
    if (isAncestor(node2, node1))
        return node2;

    for (int pow = MAX_LOG - 1; pow >= 0; pow--) {
        int ancestor = ancestors[pow][node1];
        if (ancestor != 0 && !isAncestor(ancestor, node2))
            node1 = ancestor;
    }
    return ancestors[0][node1];
}

int main() {
    fin >> n >> m;
    for (int i = 2; i <= n; i++) {
        fin >> father[i];
        l[father[i]].push_back(i);
    }

    currPos = 0;
    dfs(1, 0);
    calculateAncestors();

    for (int i = 1; i <= m; i++) {
        fin >> node1 >> node2;
        fout << getLCA(node1, node2) << '\n';
    }

    return 0;
}