Cod sursa(job #3228440)

Utilizator Bogdan345Marius Mihalache Bogdan345 Data 8 mai 2024 11:19:14
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.64 kb
//trebuie sa stiu
//pozitia nodului
//nivelul nodului
//fac rmq pe sirul care este
//turul lui euler
//in dp[i][j] retin nodul de pe nivelul cel mai mic
//[i,i+2^j-1]
#include <fstream>
#include <vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
const int MAXVAL=200100,putere=20,val=100100;
int dp[MAXVAL+1][putere+1],nivel[val+1],poz[val+1],log_2[MAXVAL+1];
vector<vector<int>>gr(val+1);
vector<int>euler;
void dfs(const int& nod,int niv){
    euler.push_back(nod);
    nivel[nod]=niv;
    poz[nod]=euler.size()-1;
    for(const auto&x:gr[nod]){
        dfs(x,niv+1);
        euler.push_back(nod);
    }
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n,m,nr;
    cin>>n>>m;
    for(int i=2;i<=n;i++){
        cin>>nr;
        gr[nr].push_back(i);
    }
    dfs(1,0);
    for(int i=0;i<euler.size();i++){
        dp[i][0]=euler[i];
    }
    for(int i=2;i<=euler.size();i++){
        log_2[i]=log_2[i/2]+1;
    }
    for(int i=euler.size()-1;i>=0;i--){
        for(int j=1;i+(1<<j)-1<=euler.size()-1;j++){
            if(nivel[dp[i][j-1]]<nivel[dp[i+(1<<(j-1))][j-1]]){
                dp[i][j]=dp[i][j-1];
            }else{
                dp[i][j]=dp[i+(1<<(j-1))][j-1];
            }
        }
    }
    int a,b,l;
    for(int i=1;i<=m;i++){
        cin>>a>>b;
        a=poz[a];
        b=poz[b];
        if(a>b){
            swap(a,b);
        }
        l=log_2[b-a+1];
        if(nivel[dp[a][l]]<nivel[dp[b-(1<<l)+1][l]]){
            cout<<dp[a][l]<<'\n';
        }else{
            cout<<dp[b-(1<<l)+1][l]<<'\n';
        }
    }
}