Cod sursa(job #3358163)

Utilizator TonyyAntonie Danoiu Tonyy Data 15 iunie 2026 00:38:49
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.86 kb
#include <bits/stdc++.h>
using namespace std;

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

const int nMax = 1e5 + 1;
const int logMax = 18;
vector<int> List[nMax];
vector<int> eulerTour, height, firstPos(nMax);

void buildEulerTour(int node, int h) {
    eulerTour.push_back(node);
    height.push_back(h);
    firstPos[node] = eulerTour.size() - 1;
    for (const int& child : List[node]) {
        buildEulerTour(child, h + 1);
        eulerTour.push_back(node);
        height.push_back(h);
    }
}

int table[2 * nMax - 1][logMax];

void buildSparseTable(int n) {
    for (int i = 0; i < n; i++) {
        table[i][0] = i;
    }
    for (int j = 1; (1 << j) <= n; j++) {
        for (int i = 0; i + (1 << j) <= n; i++) {
            if (height[table[i][j - 1]] < height[table[i + (1 << (j - 1))][j - 1]]) {
                table[i][j] = table[i][j - 1];
            }
            else {
                table[i][j] = table[i + (1 << (j - 1))][j - 1];
            }
        }
    }
}

int query(int left, int right) {
    int p = log2(right - left + 1);
    if (height[table[left][p]] < height[table[right - (1 << p) + 1][p]]) {
        return eulerTour[table[left][p]];
    }
    return eulerTour[table[right - (1 << p) + 1][p]];
}

int lca(int node1, int node2) {
    int pos1 = firstPos[node1];
    int pos2 = firstPos[node2];
    if (pos1 > pos2) {
        swap(pos1, pos2);
    }
    return query(pos1, pos2);
}

int main() {
    ios::sync_with_stdio(false);

    int n, m;
    fin >> n >> m;
    for (int i = 2; i <= n; i++) {
        int x;
        fin >> x;
        List[x].push_back(i);
    }
    buildEulerTour(1, 0);
    buildSparseTable(2 * n - 1);
    for (int i = 0; i < m; i++) {
        int node1, node2;
        fin >> node1 >> node2;
        fout << lca(node1, node2) << "\n";
    }

    return 0;
}