Cod sursa(job #1197211)

Utilizator Alexa2001Alexa Tudose Alexa2001 Data 11 iunie 2014 10:49:12
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.5 kb
#include <cstdio>
#include <vector>
#define N 100009

using namespace std;
int n,m,i,Lg[N<<1],Niv[N<<1],k,x,y,ap[N],E[N<<1],Rmq[20][N];

vector<int> g[N];

void dfs(int nv,int nod)
{
   E[++k]=nod;
   Niv[k]=nv;
   ap[nod]=k;

   vector<int> :: iterator it;

   for(it=g[nod].begin();it!=g[nod].end();++it)
  {
    dfs(nv+1,*it);

    E[++k]=nod;
    Niv[k]=nv;
  }


}

void rmq()
{
   for(int i=2; i<=k; ++i)
                Lg[i]=Lg[i >> 1]+1;
        for(int i=1; i<=k; ++i)
                Rmq[0][i]=i;

        for(int i=1; (1 << i)<k; ++i)
                for(int j=1; j<=k-(1 << i); ++j)
                {
                        int l=1 << (i - 1);

                        Rmq[i][j]=Rmq[i-1][j];
                        if(Niv[Rmq[i-1][j + l]]<Niv[Rmq[i][j]])
                                Rmq[i][j]=Rmq[i-1][j + l];
                }





}

int lca(int x,int y)
{
   int a,b,dif,l,sol,q;
   a=ap[x];
   b=ap[y];

   if(a>b) swap(a,b);

   dif=b-a+1;
   l=Lg[dif];
   sol=Rmq[l][a];

   q=dif-(1<<l);
   if(Niv[sol]>Niv[Rmq[l][a+q]]) sol=Rmq[l][a+q];

   return E[sol];




}


int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);


    scanf("%d%d",&n,&m);

    for(i=2; i<=n; ++i)
    {
        scanf("%d",&x);
        g[x].push_back(i);
    }


    dfs(0,1);

    rmq();

    for(i=1;i<=m;++i)
    {
       scanf("%d%d",&x,&y);
       printf("%d\n",lca(x,y));



    }




    return 0;
}