Cod sursa(job #1245401)

Utilizator PTAdrian64Pop-Tifrea Adrian PTAdrian64 Data 19 octombrie 2014 09:54:38
Problema Lowest Common Ancestor Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 1.44 kb
#include <cstdio>
#define nmv 100010
#include <vector>
#include <algorithm>
#include <utility>

using namespace std;

vector <int> graph[nmv];
int n,m,fel=0;
int dist[nmv<<1];
int elu[nmv<<1];
int first[nmv];
int rmq[20][nmv<<2];
int lg[nmv<<1];

void euler(int f,int l){
   elu[++fel]=f;
   dist[fel]=l;
   first[f]=fel;

   for(vector <int> :: iterator it=graph[f].begin();it!=graph[f].end();++it){
       euler(*it,l+1);
       elu[++fel]=f;
       dist[fel]=l;
   }
}

void rmq_build(){
  lg[1]=0;
  for(int i=1;i<=fel;i++){
      if(i!=1)
         lg[i]=lg[i>>1]+1;
      rmq[0][i]=i;
  }
  int l;
  for(int i=1;(1<<i)<fel;++i){
        l=1<<(i-1);
     for(int j=1;j<fel-(1<<i);j++){

         rmq[i][j]=rmq[i-1][j];
         if(dist[rmq[i][j]]>dist[rmq[i-1][j+l]])
             rmq[i][j]=rmq[i-1][j+l];
     }
  }
}

int rmq_search(int a,int b){
   int x=first[a];
   int y=first[b];
   if(y<x)
     swap(x,y);
   int d=y-x+1;
   int p=lg[d];
   int sh=d-(1<<p);

   if(dist[rmq[p][x]]>dist[rmq[p][x+sh]])
      return elu[rmq[p][x+sh]];
   return elu[rmq[p][x]];
}

int main(void){
   freopen("lca.in","r",stdin);
   freopen("lca.out","w",stdout);
   scanf("%d %d ",&n, &m);
   int x,y;
   for(int i=2;i<=n;i++){
      scanf("%d ",&x);
      graph[x].push_back(i);
   }
   euler(1,0);
   rmq_build();

   while(m--){
      scanf("%d %d ", &x, &y);
      printf("%d\n",rmq_search(x,y));
   }
}