Cod sursa(job #3287294)

Utilizator BucsMateMate Bucs BucsMate Data 17 martie 2025 15:19:17
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.12 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

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

void DFS(int node, int depth, vector<pair<int, int>> &euler_tour, vector<vector<int>> &adj, vector<int> &pos)
{
    pos[node] = euler_tour.size();
    euler_tour.push_back({node, depth});
    for(int i = 0; i < adj[node].size(); i++){
        int new_node = adj[node][i];
        DFS(new_node, depth+1, euler_tour, adj, pos);
        euler_tour.push_back({node, depth});
    }
}

int lg[200001] = {};
int minim[200001][20];
int minim_node[200001][20];

int main()
{
    int N, m;
    fin >> N >> m;
    vector<vector<int>> adj(N+1);
    for(int i = 2; i <= N; i++){
        int parent;
        fin >> parent;
        adj[parent].push_back(i);
    }
    vector<pair<int, int>> euler_tour = {{0, 0}};
    vector<int> pos(N+1);

    DFS(1, 0, euler_tour, adj, pos);
    for(int i = 2; i <= 2*N; i++){
        lg[i] = lg[i/2] + 1;
    }

    for(int i = 1; i <= 2*N-1; i++){
        minim[i][0] = euler_tour[i].second;
        minim_node[i][0] = euler_tour[i].first;
    }

    for(int j = 1; (1 << j) <= 2*N-1; j++){
        for(int i = 1; i + (1 << j) - 1 <= 2*N-1; i++){
            if(minim[i][j-1] < minim[i + (1<<(j-1))][j-1]){
                minim[i][j] = minim[i][j-1];
                minim_node[i][j] = minim_node[i][j-1];
            }
            else{
                minim[i][j] = minim[i + (1<<(j-1))][j-1];
                minim_node[i][j] = minim_node[i + (1<<(j-1))][j-1];
            }
        }
    }


    for(int i = 0; i < m; i++){
        int a, b;
        fin >> a >> b;
        int posa = pos[a], posb = pos[b];
        if(posa > posb){
            swap(posa, posb);
        }

        int exponent = lg[posb-posa+1];
        int closest_power = (1 << exponent);
        if(minim[posa][exponent] < minim[posb - closest_power + 1][exponent]){
            fout << minim_node[posa][exponent] << endl;
        }
        else{
            fout << minim_node[posb - closest_power + 1][exponent] << endl;
        }
    }

    return 0;
}