Nu aveti permisiuni pentru a descarca fisierul grader_test11.ok

Cod sursa(job #3281098)

Utilizator TimurealTimu Ionut Timureal Data 28 februarie 2025 12:47:25
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.33 kb
#include <bits/stdc++.h>
#define cin fin
#define cout fout
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int NMAX=100005;
const int LOG=20;
int n , q;
int t[NMAX];
vector<int> tree[NMAX];
int anc[NMAX][LOG];
int depth[NMAX];
void precalc(int nod , int h){
    depth[nod]=h;
    anc[nod][0]=t[nod];
    for(int i=1 ;i<LOG ; i++)
    {
        if(anc[nod][i-1]!=-1){
            anc[nod][i]=anc[anc[nod][i-1]][i-1];
        }
        else{
            anc[nod][i]=-1;
        }
    }
    for(int kid : tree[nod]){
        precalc(kid , h+1);
    }
}

int lca(int a , int b){
    if(depth[a] < depth[b]){
        swap(a , b);
    }
    int dist=depth[a]-depth[b];
    for(int i=LOG-1 ; i>=0 ; i--){
        if(dist&(1<<i)){
            a=anc[a][i];
        }
    }
    if(a==b) return a;
    for(int i=LOG-1 ; i>=0 ; i--){
        if(anc[a][i]!=anc[b][i]){
            a=anc[a][i];
            b=anc[b][i];
        }
    }
    return anc[a][0];
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin>>n>>q;
    t[1]=-1;
    for(int i=2 ; i<=n; i++)
    {
        cin>>t[i];
        tree[t[i]].push_back(i);
    }
    precalc(1 , 0);
    while(q--){
        int a , b;
        cin>>a>>b;
        cout<<lca(a ,b)<<"\n";
    }
    return 0;
}