Cod sursa(job #1201975)

Utilizator azkabancont-vechi azkaban Data 26 iunie 2014 15:51:34
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.12 kb
#include <fstream>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
typedef struct celula {
                        long nod;
                        celula *next;
                       }*lista;

lista lda[100005];
long viz[1000013],i,n,m,a,b,nr,sol(0),E[300000],H[1000013],poz[500013],RMQ[20][500013],minpos[20][500013],j,k,aux;  
                     
void add(long val, lista &p)
{
  lista r= new celula;
  r->nod=val;
  r->next=p;
  p=r;  
} 

void Eulerizare(long nod,long &sol) 
{
  viz[nod]=1;
  lista r=lda[nod];
  while (r){
            E[++sol]=nod;
            H[r->nod]=H[nod]+1;
            if (viz[r->nod]==0) Eulerizare(r->nod,sol);
            r=r->next;
            }
  E[++sol]=nod;
  poz[nod]=sol;  
}

int main()
{
  
  cin>>n>>m;
  for (i=1;i<n;++i) {
                     cin>>a;
                     add(i+1,lda[a]);
                    }
 H[1]=1;
 Eulerizare(1,sol);
 for (i=1;i<=sol;++i) RMQ[0][i]=H[E[i]], minpos[0][i]=i;
                     
 for (i=1;(1<<i)<=sol;++i) 
         for (j=1;j+(1<<i)-1<=sol;++j) { 
                                        RMQ[i][j]=min(RMQ[i-1][j],RMQ[i-1][j+(1<<(i-1))]);
                                        if(RMQ[i-1][j]<=RMQ[i-1][j+(1<<(i-1))]) minpos[i][j]=minpos[i-1][j];
                                                                          else  minpos[i][j]=minpos[i-1][j+(1<<(i-1))];
                                        }                       
  for (i=1,k=0;i<=m;++i,k=0){
                            cin>>a>>b;
                            a=poz[a]; b=poz[b];
                            if (a>b) swap(a,b);
                            if (a==b) cout<<E[minpos[0][a]]<<"\n";
                                    else {
                                          for (aux=1; aux<=(b-a); aux*=2,++k); --k;
                                          if (RMQ[k][b+1-(1<<k)]>=RMQ[k][a]) cout<<E[minpos[k][a]]<<"\n";
                                                                      else   cout<<E[minpos[k][b+1-(1<<k)]]<<"\n";
                                          }
                     }
 return 0;
}