Cod sursa(job #1245400)

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

using namespace std;

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

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

   for(vector <long> :: 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(long i=1;i<=fel;i++){
      if(i!=1)
         lg[i]=lg[i>>1]+1;
      rmq[0][i]=i;
  }
  long l,j;
  for(long i=1;(1<<i)<fel;++i){
        l=1<<(i-1);
     for(long 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];
     }
  }
}

long long rmq_search(long a,long b){
   long x=first[a];
   long y=first[b];
   if(y<x)
     swap(x,y);
   long d=y-x+1;
   long p=lg[d];
   long 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("%ld %ld ",&n, &m);
   long x,y;
   for(long i=2;i<=n;i++){
      scanf("%ld ",&x);
      graph[x].push_back(i);
   }
   euler(1,0);
   rmq_build();

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