Cod sursa(job #2392543)

Utilizator IulianOleniucIulian Oleniuc IulianOleniuc Data 30 martie 2019 10:19:21
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.56 kb
#include <cmath>
#include <vector>
#include <fstream>

#define LMAX 20
#define NMAX 200010

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

int n;
bool vis[NMAX];
std::vector<int> ad[NMAX];

int len;
int arr[NMAX];
int lvl[NMAX];
int pos[NMAX];

int q;
int dp[NMAX][LMAX];

int rmq(int lo, int hi) {
    int k = log2(hi - lo + 1);
    if (lvl[dp[lo][k]] < lvl[dp[hi - (1 << k) + 1][k]])
        return arr[dp[lo][k]];
    return arr[dp[hi - (1 << k) + 1][k]];
}

void dfs(int node, int depth) {
    vis[node] = true;
    arr[++len] = node;
    lvl[len] = depth;
    pos[node] = len;

    for (int nghb : ad[node])
        if (!vis[nghb]) {
            dfs(nghb, depth + 1);
            arr[++len] = node;
            lvl[len] = depth;
        }
}

int main() {
    fin >> n >> q;
    for (int i = 2; i <= n; i++) {
        int x; fin >> x;
        ad[i].push_back(x);
        ad[x].push_back(i);
    }

    dfs(1, 1);
    for (int i = 1; i <= len; i++)
        dp[i][0] = i;

    for (int i = len; i >= 1; i--)
        for (int j = 1; i + (1 << j) - 1 <= len; j++)
            if (lvl[dp[i][j - 1]] < lvl[dp[i + (1 << (j - 1))][j - 1]])
                dp[i][j] = dp[i][j - 1];
            else
                dp[i][j] = dp[i + (1 << (j - 1))][j - 1];

    for (int it = 0; it < q; it++) {
        int x, y;
        fin >> x >> y;

        if (pos[x] < pos[y])
            fout << rmq(pos[x], pos[y]) << '\n';
        else
            fout << rmq(pos[y], pos[x]) << '\n';
    }

    fout.close();
    return 0;
}