Cod sursa(job #595557)

Utilizator Smaug-Andrei C. Smaug- Data 13 iunie 2011 01:56:26
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.55 kb
//#include <cstdio>
#include <fstream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;

#define MAXN 100010
#define MAXLGN 18

int main(){

  // freopen("lca.in", "r", stdin);
  // freopen("lca.out", "w", stdout);
  ifstream fin ("lca.in");
  ofstream fout ("lca.out");
 
  int N, M, i, j, a, b, qp, pos, k, lca;
  static int L[MAXN<<1], E[MAXN<<1], F[MAXN<<1], dfs[MAXN], RMQ[MAXN<<1][MAXLGN], lg[MAXN<<1];
  vector<int> G[MAXN];
  vector<int>::iterator dp[MAXN];

  // scanf("%d%d", &N, &M);
  fin >> N >> M;

  for(i=2; i<=N; i++){
    //scanf("%d", &a);
    fin >> a;
    G[a].push_back(i);
  }

  memset(F, 0, sizeof(F));
  qp=0; dfs[0]=1; dp[0]=G[1].begin(); pos=0;

  while(qp>=0){
    E[++pos]=dfs[qp]; L[pos]=qp;
    if(!F[dfs[qp]])
      F[dfs[qp]]=pos;
    
    if(dp[qp] != G[dfs[qp]].end()){
      dfs[qp+1]=*dp[qp];
      ++qp;
      dp[qp]=G[dfs[qp]].begin();
    }
    else {
      --qp;
      ++dp[qp];
    }
  }

  for(i=1; i<=pos; i++)
    RMQ[i][0]=i;

  for(i=1; (1<<i)<=pos; i++)
    for(j=1; j+(1<<i)-1 <= pos; j++){
      if(L[RMQ[j][i-1]] < L[RMQ[j+(1<<(i-1))][i-1]])
	RMQ[j][i]=RMQ[j][i-1];
      else
	RMQ[j][i]=RMQ[j+(1<<(i-1))][i-1];
    }
  
  lg[1]=0;
  for(i=2; i<=pos; i++)
    lg[i]=lg[i>>1]+1;

  for(i=1; i<=M; i++){
    //scanf("%d%d", &a, &b);
    fin >> a >> b;
    a=F[a]; b=F[b];
    if(a>b)
      swap(a,b);
    k=lg[b-a+1];
    if(L[RMQ[a][k]] < L[RMQ[b-(1<<k)+1][k]])
      lca=RMQ[a][k];
    else
      lca=RMQ[b-(1<<k)+1][k];
    //printf("%d\n", E[lca]);
    fout << E[lca] << "\n";
  }
  
  return 0;

}