Cod sursa(job #1808137)

Utilizator AdrianGotcaAdrian Gotca AdrianGotca Data 17 noiembrie 2016 13:29:42
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.56 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],ans[100005][20],viz[100005],viz1[100005],pe[200005],npe,M[100005][20];
int main(){
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    scanf("%d%d",&n,&m);
    for (int i=2;i<=n;i++){
        scanf("%d",&t[i]);
    }
    DFS(1,0);
    rmq();
    for (int i=1;i<=m;i++){
        int a,b;
        scanf("%d%d",&a,&b);
        printf("%d\n",solve(viz[a],viz[b]));
    }
}

void DFS(int node,int level){
    viz1[node]=1;
    pe[++npe]=node;
    niv[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]=node;
            niv[npe]=level;
        }
    }
}

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

void rmq(){
    for (int i=1;i<=npe;i++){
        M[i][0]=niv[i];
        ans[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]);
            if (M[i][j-1]>M[i+(1<<(j-1))][j-1]){
                ans[i][j]=ans[i+(1<<(j-1))][j-1];
            }
            else {
                ans[i][j]=ans[i][j-1];
            }
        }
    }
}