Cod sursa(job #1621488)

Utilizator avaspAva Spataru avasp Data 29 februarie 2016 19:23:17
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.63 kb
#include<cstdio>
#include<vector>
using namespace std;
vector<int>v[100001];
int n,eu[200001],m,cate,nivel[200001],ap[200001],d[20][200001];
bool viz[100001];

void dfs(int nod,int niv){
    viz[nod]=true;
    eu[++cate]=nod;
    nivel[nod]=niv;
    for(int i=0;i<v[nod].size();i++)
        if(viz[v[nod][i]]==false){
            dfs(v[nod][i],niv+1);
            eu[++cate]=nod;
        }

}

int minimul(int nr1,int nr2){
    if(nr1<=nr2)
        return nr1;
    return nr2;
}

void rmq(){
    for(int i=1;i<=cate;i++)
        d[0][i]=eu[i];
    int put=1;
    int q=0;
    while(put*2<=cate){
        put*=2;
        q++;
    }
    int doila=1;
    for(int i=1;i<=q;i++){
        for(int j=1;j<=cate;j++)
            if(j+doila<=cate)
                d[i][j]=minimul(d[i-1][j],d[i-1][j+doila]);
        doila*=2;
    }
}


int queryul(int k1,int k2){
    int put=1;
    int q=0;
    while(put*2<=(k2-k1)){
        put*=2;
        q++;
    }
    return minimul(d[q][k1],d[q][k2-put+1]);
}


int main(){
    int x,n1,n2;
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n-1;i++){
        scanf("%d",&x);
        v[x].push_back(i+1);
    }
    dfs(1,0);
    /*for(int i=1;i<=cate;i++)
        printf("%d ",eu[i]);
    printf("\n");
    for(int i=1;i<=cate;i++)
        printf("%d ",nivel[eu[i]]);*/

     for(int i=1;i<=cate;i++)
        if(ap[eu[i]]==0)
            ap[eu[i]]=i;
    rmq();
    for(int i=1;i<=m;i++){
        scanf("%d%d",&n1,&n2);
        printf("%d\n",queryul(ap[n1],ap[n2]));
    }

    return 0;
}