Cod sursa(job #3271848)

Utilizator PsyDuck1914Feraru Rares-Serban PsyDuck1914 Data 27 ianuarie 2025 15:57:23
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.7 kb
#include <bits/stdc++.h>

using namespace std;

ifstream f ("lca.in");
ofstream g ("lca.out");

const int NMAX = 1e5;
int dp[18][NMAX+1], n, q;
int nivel[NMAX+1];
vector<int> adj[NMAX+1];
bool marked[NMAX+1];

void precalcul(){
    
    for(int i=2; i<=n; i++){
        
        f >> dp[0][i];
        
        adj[i].push_back(dp[0][i]);
        adj[dp[0][i]].push_back(i);
        
    }
        
    for(int i=1; (1 << i) <= n; i++)
        for(int j=1; j<=n; j++)
            dp[i][j] = dp[i-1][dp[i-1][j]];
    
}

void dfs(int nod, int niv){
    
    marked[nod] = true;
    nivel[nod] = niv;
    
    for(int next : adj[nod]){
        
        if(!marked[next])
            dfs(next, niv + 1);
        
    }
    
}

int transform(int x, int h){
    
    int y = log2(h);
    
    for(int add = y; add >= 0; add --)
        if(h >= (1 << add)){
            
            h -= (1 << add);
            x = dp[add][x];
            
        }
        
    return x;
            
}

int lca(int x, int y){
    
    int delta = abs(nivel[x] - nivel[y]);
    
    if(nivel[x] > nivel[y])
        swap(x, y);
        
    y = transform(y, delta); // x devine al delta stramos
    
    if(x == y)
        return x;
    
    for(int expo = 17; expo >= 0; expo --){
        
        if(dp[expo][x] != dp[expo][y]){
            
            x = transform(x, (1 << expo));
            y = transform(y, (1 << expo));
            
        }
            
        
    }
    
    return dp[0][x];
    
}

int main()
{
    
    
    f >> n >> q;
    
    precalcul();
    dfs(1, 1);
    
    for(int i=1; i<=q; i++){
        
        int x, y;
        f >> x >> y;
        
        g << lca(x, y) << "\n";
        
    }
    
    
    

    return 0;
}