Cod sursa(job #2840073)

Utilizator Andrei012Trache Andrei Andrei012 Data 27 ianuarie 2022 08:48:07
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.75 kb
#include <bits/stdc++.h>

using namespace std;

ifstream in("lca.in");
ofstream out("lca.out");
vector<int> v[100002];
int aint[1000001],dp[300000],parc[100001],n,m,first[100001],liniarizare[300001];
int cat;

void dfs(int nod)
{
    parc[nod]=1;
    for(auto nod2 : v[nod])

        if(parc[nod2]==0)
        {
            dp[nod2]=dp[nod]+1;
            dfs(nod2);
        }
}

void build(int nod,int l,int r){
    if(l>r)
        return;
    if(l==r){
        aint[nod]=liniarizare[l];
        return;
    }
    int mij=(l+r)/2;
    build(nod*2,l,mij);
    build(nod*2+1,mij+1,r);
    if(dp[aint[2*nod]]<dp[aint[2*nod+1]])
        aint[nod]=aint[2*nod];
    else
        aint[nod]=aint[2*nod+1];
}

int query(int nod,int l, int r, int x, int y){
    if(y<l || x>r || l>r)
        return -1;
    if(x<=l && r<=y)
        return aint[nod];
    int mij=(l+r)/2;
    int a=query(nod*2,l,mij,x,y);
    int b=query(nod*2+1,mij+1,r,x,y);
    if(a==-1)
        return b;
    if(b==-1)
        return a;
    if(dp[a]<dp[b])
        return a;
    else
        return b;
}

void euler(int nod){
    ++cat;
    liniarizare[cat]=nod;
    first[nod]=cat;
    parc[nod]=1;
    for(auto nod2 : v[nod])
        if(parc[nod2]==0)
        {
            euler(nod2);
            ++cat;
            liniarizare[cat]=nod;
        }
}

int main()
{
    int i,j,x,a,b;
    in>>n>>m;
    for(i=2;i<=n;++i){
        in>>x;
        v[x].push_back(i);
    }
    dfs(1);
    for(i=1;i<=n;++i)
        parc[i]=0;
    dp[0]=1e8;
    euler(1);
    build(1,1,2*n-1);
    for(i=1;i<=m;++i)
    {
        in>>a>>b;
        a=first[a];
        b=first[b];
        out<<query(1,1,2*n-1,min(a,b),max(a,b))<<'\n';
    }
    return 0;
}