Cod sursa(job #2838989)

Utilizator BalasaRaduBalasa Radu BalasaRadu Data 25 ianuarie 2022 00:13:57
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.88 kb
#include <bits/stdc++.h>
using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

const int dim=100009;

vector<int>v[dim];

int len,nivel[dim];
int euler[2*dim],aparitie[2*dim];

void DFS(int x,int tata){
    euler[++len]=x;
    nivel[x]=nivel[tata]+1;
    aparitie[x]=len;
    for(int y:v[x]){
        DFS(y,x);
        euler[++len]=x;
    }
}

struct SegmentTree{
    struct Nod{
        int val,poz;
    }aint[8*dim];
    Nod Merge(Nod n1,Nod n2){
        if(n1.val<n2.val){
            return n1;
        }
        return n2;
    }
    void update(int nod,int tl,int tr,int poz,Nod x){
        if(tl==tr){
            aint[nod].val=x.val;
            aint[nod].poz=x.poz;
            return;
        }
        int tm=(tl+tr)/2;
        if(poz<=tm){
            update(2*nod,tl,tm,poz,x);
        }
        else{
            update(2*nod+1,tm+1,tr,poz,x);
        }
        aint[nod]=Merge(aint[2*nod],aint[2*nod+1]);
    }
    Nod query(int nod,int tl,int tr,int l,int r){
        if(l==tl && r==tr){
            return aint[nod];
        }
        int tm=(tl+tr)/2;
        if(r<=tm){
            return query(2*nod,tl,tm,l,r);
        }
        if(l>tm){
            return query(2*nod+1,tm+1,tr,l,r);
        }
        return Merge(query(2*nod,tl,tm,l,tm),query(2*nod+1,tm+1,tr,tm+1,r));
    }
}B;

void find_lca(){
    DFS(1,0);
    for(int i=1;i<=len;i++){
        B.update(1,1,len,i,{nivel[euler[i]],euler[i]});
    }
}

int lca(int a,int b){
    a=aparitie[a];
    b=aparitie[b];
    if(a>b){
        swap(a,b);
    }
    return B.query(1,1,len,a,b).poz;
}

signed main(){
    int n,q;
        fin>>n>>q;
    for(int i=2;i<=n;i++){
        int j;
        fin>>j;
        v[j].push_back(i);
    }
    find_lca();
    while(q--){
        int l,r;
        fin>>l>>r;
        fout<<lca(l,r)<<'\n';
    }
}