Cod sursa(job #2839694)

Utilizator Andrei012Trache Andrei Andrei012 Data 26 ianuarie 2022 12:41:12
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.83 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 update(int nod ,int l, int r , int poz, int val){
    if(r==l){
        aint[nod]=val;
        return;
    }
    if(poz<l || poz>r)
        return;
    int mij=(l+r)/2;
    update(2*nod,l,mij,poz,val);
    update(2*nod+1,mij+1,r,poz,val);
    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;
    update(1,1,2*n-1,cat,nod);
    for(auto nod2 : v[nod])
        if(parc[nod2]==0)
        {
            euler(nod2);
            ++cat;
            liniarizare[cat]=nod;
            update(1,1,2*n-1,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;
    euler(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;
}