Cod sursa(job #3290712)

Utilizator Robert_NicuNicu Robert Cristian Robert_Nicu Data 31 martie 2025 17:34:27
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.63 kb
#include <bits/stdc++.h>
#define log costinelo
#define DIM 200001
using namespace std;

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

int n, q, x, y;

int i, j, idx;

int rmq[20][DIM], log[DIM], euler[DIM], depth[DIM], firstap[DIM];

vector <int> G[DIM];

void dfs(int nod, int daddy){

    depth[nod] = depth[daddy] + 1;

    euler[++idx] = nod;

    if(!firstap[nod])

        firstap[nod] = idx;

    for(auto k : G[nod]){

        if(!firstap[k])

            dfs(k, nod);

    }

    euler[++idx] = daddy;

}

int lca(int nod1, int nod2){

    int l = firstap[nod1], r = firstap[nod2];

    if(l >= r) swap(l, r);

    int d = log[r - l + 1];

    if(depth[rmq[d][l]] < depth[rmq[d][r - (1LL << d) + 1]])

        return rmq[d][l];

    else return rmq[d][r - (1LL << d) + 1];

}

int main(){

    fin >> n >> q;

    for(i = 2; i <= n; i++){

        fin >> x;

        G[x].push_back(i);

        G[i].push_back(x);

    }

    dfs(1, 0);

    idx--;

    for(i = 1; i <= idx; i++)

        rmq[0][i] = euler[i];

    for(i = 1; (1 << i) <= idx; i++){

        for(j = 1; j <= idx; j++){

            if(j + (1LL << (i-1)) <= idx){

                int nod1 = rmq[i-1][j], nod2 = rmq[i-1][j + (1LL << (i-1))];

                if(depth[nod1] <= depth[nod2])

                    rmq[i][j] = nod1;

                else rmq[i][j] = nod2;

            }else rmq[i][j] = rmq[i-1][j];

        }

    }

    for(i = 2; i <= idx; i++)

        log[i] = log[i >> 1] + 1;

    while(q--){

        fin >> x >> y;

        fout << lca(x, y) << "\n";

    }

}