Cod sursa(job #3344198)

Utilizator IleaIlea Bogdan Ilea Data 1 martie 2026 16:51:52
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.81 kb
#include<iostream>
#include<vector>
using namespace std;

#define NMAX 100001

int n,q,fap[NMAX],d[NMAX],rmq[18][2*NMAX],_lg2[2*NMAX];
vector<int>g[NMAX],euler;
void dfs(int nod,int par){
    d[nod]=d[par]+1;
    fap[nod]=euler.size();
    euler.push_back(nod);
    for(const auto&son:g[nod]){
        if(son==par)continue;
        dfs(son,nod);
        euler.push_back(nod);
    }
}
void init_rmq(void){
    n=euler.size()-1;
    _lg2[0]=-1;
    for(int i=1;i<=n;++i){
        rmq[0][i]=euler[i];
        _lg2[i]=1+_lg2[i>>1];
    }
    for(int k=1;(1<<k)<=n;++k){
        for(int i=1;i+(1<<k)-1<=n;++i){
            rmq[k][i]=(
                d[rmq[k-1][i]]<d[rmq[k-1][i+(1<<(k-1))]]
                       ?
                    rmq[k-1][i]
                       :
                    rmq[k-1][i+(1<<(k-1))]

            );
        }
    }
//    for(int k=0;(1<<k)<=n;++k){
//        for(int i=1;i+(1<<k)-1<=n;++i){
//            cout<<rmq[k][i]<<" ";
//        }
//        cout<<endl;
//    }
}
signed main(){
#ifndef LOCAL
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
#endif // LOCAL
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    cin>>n>>q;
    // graph stuff
    for(int i=2;i<=n;++i){
        int x;
        cin>>x;
        g[x].push_back(i);
        g[i].push_back(x);
    }
    euler.push_back(0);
    dfs(1,0);
    // init rmq
    init_rmq();
    // query stuff
    for(;q;--q){
        int x,y;
        cin>>x>>y;
        x=fap[x],y=fap[y];
        if(x>y)swap(x,y);
        int l=_lg2[y-x+1];
        cout<<(
            d[rmq[l][x]]<d[rmq[l][y-(1<<l)+1]]
                    ?
                rmq[l][x]
                    :
                rmq[l][y-(1<<l)+1]
        )<<"\n";
    }
    return 0;
}