Cod sursa(job #2513343)

Utilizator MarianConstantinMarian Constantin MarianConstantin Data 22 decembrie 2019 22:03:54
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.33 kb
#include <bits/stdc++.h>
#define pb push_back

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");
const int MAXN = 100010, MAXL = 20;

int dp[MAXL][MAXN], lev[MAXN], lg[MAXN], n, m;
vector<int> graph[MAXN];

void dfs(int node, int level) {
    lev[node] = level;
    for (const auto& it: graph[node])
        dfs(it, level + 1);
}

void preprocess() {
    for (int k = 1; (1 << k) <= n; ++k)
        for (int i = 1; i <= n; ++i)
            dp[k][i] = dp[k - 1][dp[k - 1][i]];
    for (int i = 2; i <= n; ++i)
        lg[i] = lg[i >> 1] + 1;
}

int lca(int x, int y) {
    if (lev[x] < lev[y])
        swap(x, y);
    int log1 = lg[lev[x]], log2 = lg[lev[y]];
    for (int k = log1; k >= 0; --k)
        if (lev[x] - (1 << k) >= lev[y])
            x = dp[k][x];
    if (x == y)
        return x;
    for (int k = log2; k >= 0; --k)
        if (dp[k][x] && dp[k][x] != dp[k][y])
            x = dp[k][x], y = dp[k][y];
    return dp[0][x];
}

int main() {
    fin >> n >> m;
    for (int i = 2; i <= n; ++i) {
        fin >> dp[0][i];
        graph[dp[0][i]].pb(i);
    }
    dfs(1, 0);
    preprocess();
    for (int i = 0; i < m; ++i) {
        int x, y;
        fin >> x >> y;
        cout << lev[x] << ' ' << lev[y] << '\n';
        fout << lca(x, y) << '\n';
    }
    return 0;
}