Cod sursa(job #2924524)

Utilizator AlexNicuNicu Alexandru AlexNicu Data 4 octombrie 2022 10:39:18
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.42 kb
#include <fstream>
#include <vector>

using namespace std;

#define NMAX (int)1e5
#define MAXLOG 17

int start[NMAX + 5], endd[NMAX + 5];

int up[NMAX + 5][MAXLOG + 1];

int timer, logg2;

vector<int> G[NMAX + 5];

void DFS(int node, int father) {
    start[node] = ++timer;
    up[node][0] = father;
    for (int i = 1; i <= logg2; i++) {
        up[node][i] = up[up[node][i - 1]][i - 1];
    }
    for (auto child : G[node]) {
        if (child != father) {
            DFS(child, node);
        }
    }
    endd[node] = ++timer;
}

bool is_stramos(int node1, int node2) {
    return start[node1] <= start[node2] && endd[node1] >= endd[node2];
}

int LCA(int node1, int node2) {
    if (is_stramos(node1, node2))
        return node1;
    if (is_stramos(node2, node1))
        return node2;
    for (int i = logg2; i >= 0; i--) {
        if (!is_stramos(up[node1][i], node2)) {
            node1 = up[node1][i];
        }
    }
    return up[node1][0];
}

void preprocess(int n) {
    timer = 0;
    logg2 = log2(n);
    DFS(1, 1);
}

ifstream cin("lca.in");
ofstream cout("lca.out");

int main()
{
    int n, m, node, node1, node2;
    cin >> n >> m;
    for (int i = 1; i <= n - 1; i++) {
        cin >> node;
        G[node].push_back(i + 1);
    }
    preprocess(n);
    for (int i = 1; i <= m; i++) {
        cin >> node1 >> node2;
        cout << LCA(node1, node2) << "\n";
    }
}