Cod sursa(job #3367591)

Utilizator medeeavasile56@gmail.comVasile Medeea [email protected] Data 8 octombrie 2026 18:54:54
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.3 kb
#include <fstream>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

ifstream cin("lca.in");
ofstream cout("lca.out");

const int NMAX=100005, MAX_POWER=21;

// a[node][i] - al 2^i lea ancestor al lui node
// suma de puteri de 2

int n,queries;

int a[NMAX][MAX_POWER];

vector<vector<int>> graph;
vector<int> sol,level,parent;

void read_and_initialise_tree_data()
{
    cin>>n>>queries;

    graph.resize(n+1,vector<int>());
    parent.resize(n+1);
    level.resize(n+1,-1);

    parent[1]=1;
    for(int i=1;i<n;i++){
        int value; cin>>value;
        parent[i+1]=value;
        graph[value].push_back(i+1);
        graph[i+1].push_back(value);
    }
}

void bfs(int start)
{
    queue<int> q; q.push(start); level[start]=1;
    while(!q.empty()){
        int node=q.front(); q.pop();
        for(int neighbor:graph[node]){
            if(level[neighbor]!=-1) continue;
            level[neighbor]=level[node]+1;
            q.push(neighbor);
        }
    }
}

void build_matrix()
{
    for(int i=1;i<=n;i++) a[i][0]=parent[i];
    for(int i=1;i<=n;i++)
    for(int j=1;j<21;j++) a[i][j]=a[a[i][j-1]][j-1];
}

int find_new_level(int& node,int dif)
{
    for(int j=20;j>=0&&(1<<j)<=dif;j--){
        node=a[node][j]; dif-=(1<<j);
    } return parent[node];
}

void compare(int& node1,int& node2)
{
    if(level[node1]>level[node2]) {
        node1=find_new_level(node1,level[node1]-level[node2]);
        return ;
    }
    if(level[node1]<level[node2])
        node2=find_new_level(node2,level[node2]-level[node1]);
}

int find_lca(int& node1,int& node2)
{
    int lca;
    for(int j=20;j>=0;j--){
        if(a[node1][j]!=a[node2][j]){
        node1=a[node1][j];
        node2=a[node2][j];}
    } return parent[node1];
}

void read_and_answer_queries()
{
    for(int i=0;i<queries;i++){
        int node1,node2; cin>>node1>>node2;
        compare(node1,node2);
        if(node1==node2){
            sol.push_back(node1); continue;
        }
        sol.push_back(find_lca(node1,node2));
    }
}
void print_solution()
{
    for(int x:sol) cout<<x<<'\n';
}

int main()
{
    read_and_initialise_tree_data();
    bfs(1);
    build_matrix();
    read_and_answer_queries();
    print_solution();
    return 0;
}