Cod sursa(job #3311201)

Utilizator vlad7654vladimir manescu vlad7654 Data 20 septembrie 2025 13:10:06
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.27 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("stramosi.in");
ofstream fout("stramosi.out");
struct binary_lifting{
    struct node{
        int depth, jump, parent;
    };
    vector<node> details;
    binary_lifting(vector<vector<int>>& mat, int root)
        :details(mat.size())
    {
    dfs(root, root, mat);
    }

    void dfs(int node, int parent, vector<vector<int>>& mat) {
        int parent2=details[parent].jump;
        details[node].depth=details[parent].depth+1;
        if(details[parent].depth-details[parent2].depth==details[parent2].depth-details[details[parent2].jump].depth){
            details[node].jump=details[parent2].jump;
        }else{
            details[node].jump=parent;
        }
        details[node].parent=parent;
        for(int it:mat[node]){
            if(it==parent)continue;
            dfs(it,node,mat);
        }
    }
    int kthParent(int node, int k){
        while(k>0 and node>0){
            if(details[node].depth-k<=details[details[node].jump].depth) {
                k-=details[node].depth-details[details[node].jump].depth;
                node=details[node].jump;
            }else{
                k--;
                node=details[node].parent;
            }
        }
        return node;
    }
    int lca(int node1, int node2){
        if(details[node1].depth<details[node2].depth){
            swap(node1,node2);
        }
        node1=kthParent(node1,details[node1].depth-details[node2].depth);
        if(node1==node2){
            return node1;
        }
        while(node1!=node2){
            if(details[node1].jump==details[node2].jump){
                node1=details[node1].parent;
                node2=details[node2].parent;
            }else{
                node1=details[node1].jump;
                node2=details[node2].jump;
            }
        }
        return node1;
    }
};
vector<vector<int> > mat;
int main(){
    int n, q;
    fin>>n>>q;
    mat.resize(n+1);
    for(int i=2;i<=n;i++){
        int val;
        fin>>val;
        mat[val].push_back(i);
        mat[i].push_back(val);
    }
    binary_lifting ans(mat, 1);
    for(int i=1;i<=q;i++){
        int nod1, nod2;
        fin>>nod1>>nod2;
        fout<<ans.lca(nod1,nod2)<<'\n';
    }
}