Cod sursa(job #700976)

Utilizator giuliastefGiulia Stef giuliastef Data 1 martie 2012 12:52:06
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.33 kb
#include <fstream>
#include <vector>
#define NMAX 100005
#define LMAX 20
using namespace std;
vector <int>G[NMAX];
int N,M,k;
int Level[NMAX<<1],Euler[NMAX<<1],First[NMAX],Lg[NMAX<<1];
int RMQ[LMAX][NMAX<<2];
void dfs(int nod, int level){
     Euler[++k]=nod;
     Level[k]=level;
     First[nod]=k;
     for(vector<int>::iterator it=G[nod].begin();it!=G[nod].end();it++){
      dfs(*it,level+1);
      Euler[++k]=nod;
      Level[k]=level;
     }
}
void rmq(){
     int i,j;
     for(i=2;i<=k;i++)
      Lg[i]=Lg[i>>1]+1;
     for(i=1;i<=k;i++)
      RMQ[0][i]=i;
     for(i=1;(1<<i)<k;i++)
      for(j=1; j<=k-(1<<i);j++){
       RMQ[i][j]=RMQ[i-1][j];
       if(Level[RMQ[i-1][j+1]]<Level[RMQ[i][j]])
        RMQ[i][j]=RMQ[i-1][j+1];
      }
}
int lca(int x, int y){
    int a,b,dif,l,s,sol;
    a=First[x], b=First[y];
    if(a>b) swap(a,b);
    dif=b-a+1;
    l=Lg[dif];
    sol=RMQ[l][a];
    s=dif-(1<<l);
    if(Level[sol]>Level[RMQ[l][a+s]])
     sol=RMQ[l][a+s];
    return Euler[sol];
}
int main(){
    int i,x,y;
    ifstream in("lca.in");
    ofstream out("lca.out");
    in>>N>>M;
    for(i=2;i<=N;i++){
     in>>x;
     G[x].push_back(i);
    }
    dfs(1,0);
    rmq();
    for(;M>0;M--){
     in>>x>>y;
     out<<lca(x,y)<<"\n";
    }
    in.close();
    out.close();
    return 0;
}