Cod sursa(job #2968028)

Utilizator Senth30Denis-Florin Cringanu Senth30 Data 20 ianuarie 2023 17:06:13
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.86 kb
#include <bits/stdc++.h>

using namespace std;
const int NMAX = 300100;
const int LGMAX = 20;

int N, M, Q;
int positionNode[NMAX], pow_2[NMAX], dad[NMAX], depth[NMAX];
vector<pair <int, int>> euler;
pair <int, int> lca[LGMAX][NMAX];
vector <int> edges[NMAX];

void read(){
    scanf("%d%d", &N, &Q);
    int x;
    for(int i = 2; i <= N; i++){
        scanf("%d", &x);
        dad[i] = x;
        edges[i].push_back(x);
        edges[x].push_back(i);
    }
}

void dfs(int node, int dad){
    euler.push_back(make_pair(depth[node], node));
    positionNode[node] = euler.size() - 1;
    for(auto it : edges[node]){
        if(it == dad)
            continue;
        depth[it] = depth[node] + 1;
        dfs(it, node);
        euler.push_back(make_pair(depth[node], node));
    }
}

void buildRMQ(){
    M = euler.size() - 1;
    for(int i = 1; i <= M; i++)
        lca[0][i] = euler[i];

    for(int k = 1; k < LGMAX; k++)
        for(int i = 1; i <= M; i++){
            lca[k][i] = lca[k - 1][i];
            if(lca[k][i].first > lca[k - 1][i + (1 << (k - 1))].first)
                lca[k][i] = lca[k - 1][i + (1 << (k - 1))];
        }

    for(int i = 2; i < NMAX; i++)
        pow_2[i] = pow_2[i / 2] + 1;
}

int main() {

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

    read();

    euler.push_back(make_pair(0, 0));
    dfs(1, 0);

    buildRMQ();

    int x, y, length;
    pair <int, int> ans;
    while(Q--){
        scanf("%d%d", &x, &y);
        x = positionNode[x];
        y = positionNode[y];
        if(x > y)
            swap(x, y);
        length = pow_2[y - x];

        ans = lca[length][x];
        if(ans.first > lca[length][y - (1 << length) + 1].first)
            ans = lca[length][y - (1 << length) + 1];
        printf("%d\n", ans.second);
    }

    return 0;
}