Cod sursa(job #1810718)

Utilizator CodrutLemeniCodrut Lemeni CodrutLemeni Data 20 noiembrie 2016 14:47:46
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.59 kb
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <bitset>
#include <vector>
#define N 210000
#define LOGN 25

using namespace std;

int val[N];

int first[N<<1], h[N<<1],parg[N<<1];
int rmq[N<<1][LOGN], lg[N];

int viz[N];
vector <int> muc[N];
int nod  ,n;

void dfs( int k ,int lvl){
    vector < int > :: iterator it;

    first[k]= ++nod;
    h[nod]=lvl;
    parg[nod ] = k;

    for ( it = muc [ k ].begin() ; it != muc[ k ].end() ; it++ ){

        if( first [*it]){
            continue;
        }
        dfs(*it,lvl+1);

        h[ ++nod ] = lvl;
        parg[ nod  ]= k;
    }

}

int minrmq(int a ,int b){

    if(h[ a ] > h[ b ]){
        return b;
    }
    return a;
}

void gen_lca(){
    int i,j,pow2;

    for(i=2;i<=nod;i++){
        lg[i]=lg[i/2]+1;
    }

    for(i = 1 ; i <= nod ; i++){
        rmq[i][0]=i;
    }

    for ( j = 1 ,pow2=1 ; (pow2 <<1) <=nod ; pow2 <<= 1 , j++){
        for(i = 1 ; i +pow2 <= nod ; i++){
            rmq[i][j] = minrmq( rmq[i][j-1] , rmq[i+pow2][j-1] );
        }
    }

}


int lca( int x ,int y){
    static int vlg;

    if( x >  y ){
        int t = x;
        x = y;
        y = t;
    }

    vlg = lg [ y - x + 1 ];

    return minrmq( rmq[x][vlg], rmq[ y - (1<<vlg) +1][vlg]   );

}

int main(){
    int m,i,x,y,rad;
    int vallca,vmax= 0;

    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);


    scanf("%d%d",&n,&m);

//    for(i = 1 ; i <= n; i++ ){
//        scanf("%d", &val[i]);
//    }

    for(i=2 ;i <= n ; i++){
       // scanf("%d%d",&x,&y);
        y=i;
        scanf("%d",&x);
        muc[x].push_back(y);
        viz[y]=1;
    }

    for(i=1;i<=n;i++){
        if(viz[i]==0){
            rad=i;
        }
    }
    rad=1;
    dfs(rad,0);


    gen_lca();

    int lx,ly;
    for ( i =0;i<m;i++){
        scanf("%d%d",&x,&y);
        vallca = lca(first[x] ,first [y]);
        vallca = parg [vallca];
        printf("%d\n",vallca);
//        if(val[ vallca ] > vmax){
//            vmax = val[ vallca ];
//            lx = x;
//            ly = y;
//        }else if ( val[ vallca ] == vmax){
//            if( x < lx){
//                vmax = val[ vallca ];
//                lx = x;
//                ly = y;
//            }else if ( x == lx){
//                if( y < ly){
//                    vmax = val[ vallca ];
//                    lx = x;
//                    ly = y;
//                }
//
//            }
//
//        }
    }

 //   printf("%d %d %d",vmax ,lx,ly);

    return 0;
}