Cod sursa(job #2084642)

Utilizator sergiudnyTritean Sergiu sergiudny Data 9 decembrie 2017 11:13:31
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.82 kb
#include <bits/stdc++.h>
#define DM 100005
#define pb push_back
#define pii pair<int,int>
#define x first
#define y second
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");

int n,m,lg,a,b;
vector<int>fiu[DM];
int niv[DM];
int parinte[DM],parinte2[DM];
vector<int>aux;

void construct(int nod){
    int sz = aux.size();
    parinte2[nod]=(sz-lg>=0?aux[sz-lg]:0);
    aux.pb(nod);
    for(auto i:fiu[nod])
        construct(i);
    aux.pop_back();
}

void dfs(int nod,int currNiv){
    niv[nod]=currNiv;
    lg=max(lg,currNiv);
    for(auto i:fiu[nod])
        dfs(i,currNiv+1);
}

pii makeSameLevel(int a,int b){
    if(niv[a]<niv[b]) swap(a,b);
    int aux = a;
    while(niv[aux]!=niv[b]){
        if(niv[aux]-niv[b]>=lg)
            aux=parinte2[aux];
        else
            aux=parinte[aux];
    }
    return {aux,b};
}

void lca(int a,int b){
    pii aux = makeSameLevel(a,b);
    int aux1=aux.first,aux2=aux.second;
    int level = niv[aux1];
    while(aux1!=aux2){
        if(level>lg){
            if(parinte2[aux1]==parinte2[aux2]){
                for(int i=1;i<=lg && aux1!=aux2;++i){
                    aux1=parinte[aux1];
                    aux2=parinte[aux2];
                }
            }
            else{
                aux1=parinte2[aux1];
                aux2=parinte2[aux2];
                level-=lg;
            }
        }
        else{
            aux1=parinte[aux1];
            aux2=parinte[aux2];
            level-=1;
        }
    }
    fout<<aux1<<'\n';
}

int main()
{
    fin>>n>>m;
    for(int i=2;i<=n;++i){
        fin>>a;
        fiu[a].pb(i);
        parinte[i]=a;
    }
    dfs(1,1);
    lg=sqrt(lg);
    construct(1);
    for(int i=1;i<=m;++i){
        fin>>a>>b;
        lca(a,b);
    }
    return 0;
}