Cod sursa(job #1320744)

Utilizator sicsicFMI-Coteanu Vlad sicsic Data 18 ianuarie 2015 14:16:32
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 2.54 kb
#include<fstream>
using namespace std;
int T[100001],U[100001],D[100001],C[100001],n,q,k,P[100001],A[100001],i,Poz[100001],v[500001],val=0,a,b,mx=999999,x,y,poz;
struct lista{int nod;
             lista *leg;
             } *G[100001],*p;
void adaug(int i,int j)
{
    lista *p;
    p=new lista;
    p->nod=j;
    p->leg=G[i];
    G[i]=p;
}
void citire()
{
    scanf("%d", &n);
    scanf("%d", &q);
    int i,k;
    for(k=2;k<=n;++k)
    {
        scanf("%d", &i);
        T[k]=i;
        adaug(i,k);
    }
}
void BFS(int start)
{
    lista *p;
    int st,dr,nod;
    st=dr=1;
    C[1]=start;
    U[st]=1;
    for(D[start]=0;st<=dr;st++)
    {
        nod=C[st];
        for(p=G[nod];p;p=p->leg)
            if(!U[p->nod]) {
                            dr++;
                            C[dr]=p->nod;
                            U[p->nod]=1;
                            D[p->nod]=D[nod]+1;
                          }
    }
}
void Euler(int start)
{
    P[++k]=start;
    Poz[start]=k;
    A[k]=D[start]+1;
    lista *p;
    for(p=G[start];p;p=p->leg)
    {
        Euler(p->nod);
        P[++k]=start;
        A[k]=D[start]+1;
    }
}
void cng(int nod,int st,int dr)
{
    if(st==dr)
    {
        v[nod]=val;
        return;
    }
    int mij=(st+dr)/2;
    if(poz<=mij) cng(nod*2,st,mij);
    else cng(nod*2+1,mij+1,dr);
    v[nod]=min(v[nod*2],v[nod*2+1]);
}
void rmq(int nod,int st,int dr)
{
    if(st>=a&&dr<=b)
    {
        if(v[nod]<mx) mx=v[nod];
        return;
    }
    int mij=(st+dr)/2;
    if(a<=mij) rmq(nod*2,st,mij);
    if(b>mij) rmq(nod*2+1,mij+1,dr);
}
void querry()
{
    int i;
    for(i=1;i<=k;++i)
    {
        val=A[i];
        poz=i;
        cng(1,1,k);
    }
 //   for(i=1;i<=k;++i) printf("%d ", v[i]);
 //   printf("\n");
 //   for(i=1;i<=n;++i) printf("%d ", T[i]);
 //   printf("\n");
 //   for(i=1;i<=n;++i) printf("%d ", D[i]);
 //   printf("\n");
    for(i=1;i<=q;++i)
    { scanf("%d", &x);
      scanf("%d", &y);
      mx=999999;
      a=min(Poz[x],Poz[y]);
      b=max(Poz[x],Poz[y]);
  //    printf("%d ", a);
  //    printf("%d \n", b);
      rmq(1,1,k);
  //    printf("%d \n", mx);
      while(D[x]+1!=mx) x=T[x];
      printf("%d \n", x);
    }
}
int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    citire();
    BFS(1);
    Euler(1);
  //  for(i=1;i<=k;++i) printf("%d ", P[i]);
  //  printf("\n");
   // for(i=1;i<=k;++i) printf("%d ", A[i]);
  //  printf("\n");
    querry();
    return 0;
}