Cod sursa(job #2974164)

Utilizator Vlad_NistorNIstor Vlad Vlad_Nistor Data 3 februarie 2023 14:39:40
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.5 kb
#include <bits/stdc++.h>
using namespace std;
#define MAX_BIT 18

vector<int> arbore[100006];
int tata[100006];
int nivel[100006], p_start[100005], p_end[100005], stramosi[MAX_BIT][100005];
int psize = 0;
int n, m;
void dfs(int nod, int lvl = 1){
    nivel[nod] = lvl;
    p_start[nod] = ++psize;
    for(int i = 0;i<arbore[nod].size();i++){
        dfs(arbore[nod][i], lvl+1);
    }
    p_end[nod] = ++psize;
}

bool stramos(int x, int y){
    return p_start[x] <= p_start[y] && p_end[y] <= p_end[x];
}


void strm(){
    /// precalculam stramosii pentru ficare nod al 2 ^ k-lea mostenitor
    for(int i = 1;i<=n;i++){
        /// pentru fiecare nod primul lui stramos va fi exact tatal sau
        stramosi[0][i] = tata[i];
    }
    for(int i = 1;i<=MAX_BIT - 1;i++){
        for(int j = 1;j<=n;j++){
            stramosi[i][j] = stramosi[i-1][stramosi[i-1][j]];
        }
    }
}

int lca(int x, int y){
    if(stramos(x,y)){
        return x;
    }
    if(stramos(y,x)){
        return y;
    }
    for(int i = MAX_BIT-1;i>=0;i--){
        int smt = stramosi[i][x];
        if(smt != 0 && !stramos(smt, y))x = smt;
    }
    return stramosi[0][x];
}


int main(void){
    ofstream cout("lca.out");
    ifstream cin("lca.in");
    cin >> n >> m;
    for(int i = 2;i<=n;i++){
        cin >> tata[i];
        arbore[tata[i]].push_back(i);
    }
    dfs(1);
    strm();
    while(m--){
        int x, y;
        cin >> x >> y;
        cout << lca(x,y) << '\n';
    }
}