Cod sursa(job #3271880)

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

using namespace std;

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

const int NMAX = 1e5;
const int MMAX = 1e5;

struct ura{
    
    int nod;
    int niv;
    
};

int first[NMAX + 1];

ura v[2 * MMAX + 2], rmq[23][2 * MMAX + 2];
int n, q, tata[NMAX+1];
int nivel[NMAX + 1];
vector<int> adj[NMAX+1];
bool marked[NMAX+1];

int cnt = 0;

ura min(ura a, ura b){
    
    if(a.niv <= b.niv)
        return a;
        
    return b;
    
}

int calc_min(int x, int y){
    
    if(x > y)
        swap(x, y);
        
    int dist = log2(y - x + 1);
    
    return min(rmq[dist][x], rmq[dist][y - (1 << dist) + 1]).nod;
    
}


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



int main()
{
    
    f >> n >> q;
    
    for(int i=2; i<=n; i++){
        
        f >> tata[i];
        
        adj[i].push_back(tata[i]);
        adj[tata[i]].push_back(i);
        
        
    }
    
    dfs(1, 1);
    
    n = cnt;
    
    // for(int i=1; i<=n; i++){
        
    //     cout << v[i].cnt << ' ' << v[i].nod << ' ' << v[i].niv << endl;
        
    // }
    
    for(int i=1; i<=n; i++)
        rmq[0][i] = v[i];
        
    for(int i = 1; (1 << i) <= n; i++){
        
        for(int j = 1; j <= n; j++){
            
            rmq[i][j] = min(rmq[i-1][j], rmq[i-1][j + (1 << (i-1))]);
            
        }
        
    }
    
    
    for(int i=1; i<=q; i++){
        
        int x, y;
        f >> x >> y;
        
        int start = first[x];
        int final = first[y];
        
        if(final < start)
            swap(final, start);
        
        g << calc_min(start, final) << "\n";
        
    }
    
    

    return 0;
}