Cod sursa(job #391677)

Utilizator blasterzMircea Dima blasterz Data 6 februarie 2010 01:20:41
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.32 kb
#include <stdio.h>
#include<iostream>
#include<fstream>
#include<vector>
#include <cstdio>

#define dim 8192
char ax[dim];
int pz;


inline void cit(int &x)
{
	x = 0;
	while(ax[pz] < '0' || ax[pz] > '9')
		if(++pz == dim) 
			fread(ax,1,dim,stdin),pz = 0;

	while(ax[pz] >= '0' && ax[pz] <= '9')
	{
		x = x * 10 + ax[pz] - '0';
		if(++pz == dim)
			fread(ax,1,dim,stdin),pz = 0;
	}
}

using namespace std;
vector<int> G[100005];

#define foreach(V) for(typeof (V).begin() it = (V).begin(); it != (V).end(); it++)
#define min(muie,tuie) (muie)<(tuie)?(muie):(tuie)
struct data{int lev;
int eul;
};
vector<data> E;
data aux;
int M[200005][20],lg[200005],H[100005],n,m;

//ifstream fin("lca.in");
void dfseuler(int nod,int niv)
{
  aux.lev=niv;
  aux.eul=nod;
  E.push_back(aux);
   H[nod]=E.size()-1;
  foreach(G[nod])/// nu mai punem conditia de vizitare datorita modului in care am construit listele de adiacenta
  {
      dfseuler(*it,niv+1);
     aux.lev=niv;
     aux.eul=nod;
     E.push_back(aux);
  }



}
void rmq()
{int i,j;
    lg[1]=0;
    for(i=2;i<=2*n;i++)
    lg[i]=lg[i/2]+1;
    for(i=1;i<=E.size()-1;i++)
      M[i][0]=i;
    for(j=1;j<=lg[E.size()-1];j++)
      for(i=1;i<=E.size()-(1<<j);i++)
      {if( E[M[i][j-1]].lev<E[M[i+(1<<(j-1))][j-1]].lev)
        M[i][j]= M[i][j-1];
        else
        M[i][j]= M[i+(1<<(j-1))][j-1];
      }


}

void citire()
{int x,i;

	freopen("lca.in","r",stdin);

	cit(n); cit(m);

//fin>>n>>m;

for(i=1;i<=n-1;i++)
   {//fin>>x;
	   cit(x);
   G[x].push_back(i+1);}///adaugam doar fii deci daca trecem de la tata la fiu,
   /// tatal nu se va afla in lista fiului deci nu vom putea sa merge de la fiu la tata si nu vom avea ciclu infinit in cazul de fata


}

int main()
{ int i, tav,dra,high,low;
    citire();
    aux.lev=-1;
    aux.eul=-1;
    E.push_back(aux);
    dfseuler(1,0);
    rmq();
    freopen("lca.out", "w", stdout);
    for(i=1;i<=m;i++)
     {//fin>>tav>>dra;
	     cit(tav); cit(dra);
     if(H[tav]>H[dra])
      {high=H[tav];
      low=H[dra];
      }
      else
      {high=H[dra];
      low=H[tav];
      }

      if(E[M[low][lg[high-low+1]]].lev>E[M[high-(1<<lg[high-low+1])+1][lg[high-low+1]]].lev)

         printf("%d\n",E[M[high-(1<<lg[high-low+1])+1][lg[high-low+1]]].eul);
         else

          printf("%d\n",E[M[low][lg[high-low+1]]].eul);
     }
    //fin.close();

    return 0;
}