Cod sursa(job #3348984)

Utilizator RaduCalisovCalisovRadu RaduCalisov Data 24 martie 2026 22:00:05
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.51 kb
#include <bits/stdc++.h>
using namespace std;

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

int n,q;
vector<int> depths;
vector<int> lg;
vector<vector<int>> v;
vector<vector<int>> bn;

void dfs(int nod,int p,int depth){
    depths[nod] = depth;

    bn[nod][0] = p;

    for(int i = 1;i<=lg[n];i++){
        bn[nod][i] = bn[bn[nod][i-1]][i-1];

        if(bn[nod][i] == 0)
            break;
    }

    for(int i = 0 ; i < v[nod].size();i++){
        int newnod = v[nod][i];

        if(newnod == p)
            continue;

        dfs(newnod,nod,depth + 1);
    }
}

void querry(int x,int y){

    if(depths[x] < depths[y])
        swap(x,y);

    int d = depths[x] - depths[y];

    for(int i = 0;i<=lg[d];i++){
        if(d & (1<<i))
            x = bn[x][i];
    }

    if(x == y){
        fout<<x<<"\n";
        return;
    }

    for(int i = lg[depths[y]];i>=0;i--){
        if(bn[y][i] != bn[x][i]){
            y = bn[y][i];
            x = bn[x][i];
        }
    }

    fout<<bn[x][0]<<"\n";
}

int main(){
    fin>>n>>q;

    lg.resize(n+1);

    lg[1] = 0;

    for(int i=2;i<=n;i++)
        lg[i] = lg[i/2] + 1;

    v.resize(n+1);
    bn.resize(n+1,vector<int>(lg[n]+1,0));
    depths.resize(n+1);

    for(int i=2;i<=n;i++){
        int pi;
        fin>>pi;

        v[i].push_back(pi);
        v[pi].push_back(i);
    }

    dfs(1,0,0);

    for(int i=1;i<=q;i++){
        int x,y;
        fin>>x>>y;

        querry(x,y);
    }
}