Cod sursa(job #3311267)

Utilizator vlad7654vladimir manescu vlad7654 Data 20 septembrie 2025 18:47:04
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.22 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int LOGMAX=15;
struct rmq{
    vector<vector<int> > mat;
    vector<int> lg;
    rmq(vector<int> &v, int n)
    :mat(LOGMAX+5, vector<int>(n+5, 0)), lg(n+1)
    {
        build_log(n);
        build_rmq(v, n);

    }
    void build_log(int n){
        lg[1]=0;
        for(int i=2;i<=n;i++){
            lg[i]=lg[i/2]+1;
        }
    }
    void build_rmq(vector<int> &v, int n){
        for(int i=1;i<=n;i++){
            mat[0][i]=i;
        }
        for(int i=1;i<=lg[n];i++){
            for(int j=1;j+(1<<i)-1<=n;j++){
                if(v[mat[i-1][j]]<=v[mat[i-1][j+(1<<(i-1))]]){
                    mat[i][j]=mat[i-1][j];
                }else{
                    mat[i][j]=mat[i-1][j+(1<<(i-1))];
                }
            }
        }
    }
    int query(vector<int> &v, int L, int R){
        int dist=lg[R-L+1];
        if(v[mat[dist][L]]<v[mat[dist][R-(1<<dist)+1]]){
            return mat[dist][L];
        }else{
            return mat[dist][R-(1<<dist)+1];
        }
    }
};
vector<bool> vizitat;
vector<int> euler, first_ap, nivel;
vector<vector<int> > graph;
void dfs(int nod, int level){
    vizitat[nod]=1;
    euler.push_back(nod);
    nivel.push_back(level);
    for(auto it:graph[nod]){
        if(vizitat[it]==0){
            dfs(it, level+1);
            nivel.push_back(level);
            euler.push_back(nod);
        }

    }
}
int main(){
    int n, q;
    fin>>n>>q;
    vector<int> test;
    vizitat.resize(n+1);
    graph.resize(n+1);
    first_ap.resize(n+1);
    for(int i=2;i<=n;i++){
        int val;
        fin>>val;
        graph[val].push_back(i);
        graph[i].push_back(val);
    }
    euler.push_back(0);
    nivel.push_back(0);
    dfs(1, 0);
    for(int i=1;i<euler.size();i++){
        if(first_ap[euler[i]]==0){
            first_ap[euler[i]]=i;
        }
    }
    rmq ans(nivel, nivel.size()-1);
    for(int i=1;i<=q;i++){
        int l, r;
        fin>>l>>r;
        l=first_ap[l];
        r=first_ap[r];
        if(l>r){
            swap(l,r);
        }

        fout<<euler[ans.query(nivel, l, r)]<<'\n';
    }
}