Cod sursa(job #1621525)

Utilizator avaspAva Spataru avasp Data 29 februarie 2016 19:44:09
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.81 kb
#include<cstdio>
#include<vector>
using namespace std;
vector<int>v[100001];

struct chestie{int nivv,nod;};
chestie nivel[200001],d[20][200001];

int n,eu[200001],m,cate,ap[200001];
bool viz[100001];

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

}

chestie minimul(chestie nr1,chestie nr2){
    if(nr1.nivv<=nr2.nivv)
        return nr1;
    return nr2;
}

void rmq(){
    for(int i=1;i<=cate;i++){
        d[0][i].nivv=nivel[eu[i]].nivv;
        d[0][i].nod=nivel[eu[i]].nod;
    }
    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++;
    }
    chestie rez=minimul(d[q][k1],d[q][k2-put+1]);
    return rez.nod;

}


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;
}