Cod sursa(job #1808115)

Utilizator AdrianGotcaAdrian Gotca AdrianGotca Data 17 noiembrie 2016 12:51:59
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.21 kb
#include <bits/stdc++.h>

using namespace std;

void DFS(int,int);
void rmq();
int solve(int,int);
int n,m,t[100005],niv[100005],viz[100005],viz1[100005],pe[200005],npe,M[100005][20];
int main(){
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    cin>>n>>m;
    for (int i=2;i<=n;i++){
        cin>>t[i];
    }
    DFS(1,0);
    rmq();
    for (int i=1;i<=m;i++){
        int a,b;
        cin>>a>>b;
        int nivel=solve(viz[a],viz[b]);
        while (nivel<niv[a]){
            a=t[a];
        }
        cout<<a<<'\n';
    }
}

void DFS(int node,int level){
    viz1[node]=1;
    niv[node]=level;
    pe[++npe]=level;
    if (!viz[node]){
        viz[node]=npe;
    }
    for (int i=1;i<=n;i++){
        if (t[i]==node&&!viz1[i]){
            DFS(i,level+1);
            pe[++npe]=level;
        }
    }
}

int solve(int a,int b){
    int l=b-a+1;
    return min(M[a][(int)log2(l)],M[b-(1<<(int)log2(l))+1][(int)log2(l)]);
}

void rmq(){
    for (int i=1;i<=npe;i++){
        M[i][0]=pe[i];
    }
    for (int j=1;(1<<j)<=npe;j++){
        for (int i=1;i+(1<<(j-1))<=npe;i++){
            M[i][j]=min(M[i][j-1],M[i+(1<<(j-1))][j-1]);
        }
    }
}