Cod sursa(job #2472733)

Utilizator Leonard1998Olariu Leonard Leonard1998 Data 12 octombrie 2019 19:15:49
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.06 kb
#include <bits/stdc++.h>
#define NMAX (int)(1e5 + 5)
#define mp make_pair
#define leftChild node<<1
#define rightChild node<<1 | 1
#define inf 0x3f3f3f

using namespace std;

int euler[2 *NMAX], depth[2 * NMAX], first[2 * NMAX];
pair<int, int> depth_aint[4 * (2 * NMAX)];
vector<int> g[NMAX];

int ind, nivel;
void dfs(int k, int lst) {
    euler[++ind] = k;
    depth[ind] = nivel;
    first[k] = ind;

    for (int child : g[k]) {
        if (child == lst) continue;

        ++nivel;
        dfs(child, k);
        --nivel;

        euler[++ind] = k;
        depth[ind] = nivel;
    }
}

void build(int node, int l, int r) {
    if (l == r)
        depth_aint[node] = mp(depth[l], l);
    else {
        int mid = (l + r) / 2;
        build (leftChild, l, mid);
        build (rightChild, mid+1, r);

        if (depth_aint[leftChild].first <= depth_aint[rightChild].first)
            depth_aint[node] = depth_aint[leftChild];
        else depth_aint[node] = depth_aint[rightChild];
    }
}

pair<int, int> query(int node, int l, int r, int x, int y) {
    if (l >= x && r <= y) return depth_aint[node];

    int mid = (l + r) / 2;

    pair<int, int> lRet = mp(inf, 0);
    pair<int, int> rRet = mp(inf, 0);

    if (mid >= x) lRet = query(leftChild, l, mid, x, y);
    if (mid+1 <= y) rRet = query(rightChild, mid+1, r, x, y);

    if (lRet.first <= rRet.first)
        return lRet;
    return rRet;
}

int main()
{
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);

    int n, q;
    scanf ("%d %d", &n, &q);

    for (int i = 2; i <= n; ++i) {
        int j;
        scanf("%d", &j);

        g[i].push_back(j);
        g[j].push_back(i);
    }

    dfs(1, -1);
    build(1, 1, ind);

    while (q--) {
        int node1, node2;
        scanf("%d %d", &node1, &node2);

        int x = min(first[node1], first[node2]);
        int y = max(first[node1], first[node2]);
        pair<int, int> ans = query(1, 1, ind, x, y);

        printf("%d\n", euler[ans.second]);
    }

    return 0;
}