Cod sursa(job #3277484)

Utilizator Barbu_MateiBarbu Matei Barbu_Matei Data 16 februarie 2025 13:01:54
Problema Range minimum query Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.63 kb
#include <bits/stdc++.h>
using namespace std;

int n, q;
vector<int> v[100001], depth;
int depthNode[200001], last[100001];
int rmq[200001][19], logn[200001];

void eulerDfs(int node, int node_depth) {
    depth.push_back(node_depth);
    depthNode[depth.size() - 1] = node;
    last[node] = depth.size() - 1;
    for (int i = 0; i < v[node].size(); ++i) {
        eulerDfs(v[node][i], node_depth + 1);
        depth.push_back(node_depth);
        depthNode[depth.size() - 1] = node;
        last[node] = depth.size() - 1;
    }
}

bool comp(int x, int y) {
    return depth[x] < depth[y];
}

int lca(int x, int y) {
    int t1 = min(last[x], last[y]);
    int t2 = max(last[x], last[y]);
    int maxLog = logn[t2 - t1 + 1];
    int ans = min(rmq[t1][maxLog], rmq[t2 - (1 << maxLog) + 1][maxLog], comp);
    return depthNode[ans];
}

void calcRmq() {
    logn[2] = 1;
    for (int i = 3; i <= depth.size(); ++i) {
        logn[i] = logn[i / 2] + 1;
    }
    for (int i = 0; i < depth.size(); ++i) {
        rmq[i][0] = i;
    }
    for (int p = 1; p <= logn[depth.size()]; ++p) {
        for (int i = 0; i + (1 << p) - 1 < depth.size(); ++i) {
            rmq[i][p] = min(rmq[i][p - 1], rmq[i + (1 << (p - 1))][p - 1], comp);
        }
    }
}

int main() {
    ifstream cin("lca.in");
    ofstream cout("lca.out");
    cin >> n >> q;
    for (int i = 2; i <= n; ++i) {
        int father;
        cin >> father;
        v[father].push_back(i);
    }
    eulerDfs(1, 0);
    calcRmq();
    for (int i = 1; i <= q; ++i) {
        int x, y;
        cin >> x >> y;
        cout << lca(x, y) << "\n";
    }
}