Cod sursa(job #2956902)

Utilizator mateicosCostescu Matei mateicos Data 21 decembrie 2022 04:01:34
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.69 kb
#include <cstdio>
#include <vector>
#include <cmath>
#include <time.h>
#include <algorithm>
#define NMAX 1000005
#define RMQ_SIZE 25


using namespace std;

vector <int> G[NMAX];
int lvl[NMAX], eu[2 * NMAX], lg[2 * NMAX], st[2 * NMAX], rmq_mat[RMQ_SIZE][2 * NMAX], n_eu;

void dfs(int nod, int lv) {
    eu[++n_eu] = nod;
    lvl[n_eu] = lv;
    st[nod] = n_eu;
    for(int i = 0; i < G[nod].size();i++) {
        dfs(G[nod][i], lv + 1);
        eu[++n_eu] = nod;
        lvl[n_eu] = lv;
    }
}

void rmq() {
    int i, j, l;
    for (i = 2; i <= n_eu; i++)
        lg[i] = lg[i >> 1] + 1;
    for (i = 1; i <= n_eu; i++)
        rmq_mat[0][i] = i;

    for (i  = 1; (1 << i) < n_eu; i++) {
        l = 1 << i;
        for (j = 1; j + l <= n_eu; j++) {
            rmq_mat[i][j] = rmq_mat[i - 1][j];
            if (lvl[rmq_mat[i - 1][j + (l >> 1)]] < lvl[rmq_mat[i][j]])
                rmq_mat[i][j] = rmq_mat[i - 1][j + (l >> 1)];
        }
        l = 1<<i;
    }
}

inline int query(int a, int b) {
    a = st[a];
    b = st[b];
    if (a > b)
        swap(a, b);
    if (lvl[rmq_mat[lg[b - a + 1]][a]] < lvl[rmq_mat[lg[b - a + 1]][b - (1 << lg[b - a + 1]) + 1]])
        return eu[rmq_mat[lg[b - a + 1]][a]];
    return eu[rmq_mat[lg[b - a + 1]][b - (1 << lg[b - a + 1]) + 1]];
}

int main()
{
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    int n, m, i, a, b;
    scanf("%d%d", &n, &m);
    for (i = 1; i < n; i++) {
        scanf("%d", &a);
        G[a].push_back(i + 1);
    }
    dfs(1, 1);
    rmq();
    for (i = 0; i < m; i++) {
        scanf("%d%d", &a, &b);
        printf("%d\n", query(a, b));
    }

    return 0;
}