Cod sursa(job #1323177)

Utilizator sicsicFMI-Coteanu Vlad sicsic Data 20 ianuarie 2015 19:38:18
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 2.36 kb
#include<fstream>
#define dim 8192
using namespace std;
ofstream g("lca.out");
int pozmx,U[100001],C[100001],n,q,k,P[100001],hg,A[100001],i,Poz[100001],v[600001],val=0,a,b,mx=999999,x,y,poz,N[600001];
struct lista{int nod;
             lista *leg;
             } *G[100001],*p;
char ax[dim];

int pz;

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;

}

}
void adaug(int i,int j)
{
    lista *p;
    p=new lista;
    p->nod=j;
    p->leg=G[i];
    G[i]=p;
}
void citire()
{
    cit(n); cit(q);
    int i,k;
    for(k=2;k<=n;++k)
    {
        cit(i);
        adaug(i,k);
    }
}
void Euler(int start)
{
    P[++k]=start;
   // g<<start<<'\n';
    Poz[start]=k;
    A[k]=hg+1;
    lista *p;
    for(p=G[start];p;p=p->leg)
    {
        hg++;
        Euler(p->nod);
        hg--;
        P[++k]=start;
        A[k]=hg+1;
    }
}
void cng(int nod,int st,int dr)
{
    if(st==dr)
    {
        v[nod]=A[st];
        N[nod]=st;
        return;
    }
    int mij=(st+dr)/2;
    cng(nod*2,st,mij);
    cng(nod*2+1,mij+1,dr);
    if(v[nod*2]<=v[nod*2+1])
    {
        v[nod]=v[nod*2];
        N[nod]=N[nod*2];
    }
    else
    {
        v[nod]=v[nod*2+1];
        N[nod]=N[nod*2+1];
    }
}
void rmq(int nod,int st,int dr)
{
    if(st>=a&&dr<=b)
    {
        if(v[nod]<=mx)
        { mx=v[nod];
          pozmx=N[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;
    cng(1,1,k);
   // for(i=1;i<=k;++i) printf("%d ", v[i]);
   // printf("\n");
    for(i=1;i<=q;++i)
    { cit(x); cit(y);
      mx=999999;
      a=min(Poz[x],Poz[y]);
      b=max(Poz[x],Poz[y]);
  //    printf("%d ", a);
  //    printf("%d \n", b);
      pozmx=0;
      rmq(1,1,k);
      //printf("%d ",mx);
      g<<P[pozmx]<<'\n';
   //   while(D[x]+1!=mx) x=T[x];
    //  printf("%d \n", x);
    }
}
int main()
{
    freopen ("lca.in", "r", stdin);
    citire();
    hg=0;
    Euler(1);
   /* for(i=1;i<=k;++i) g<<P[i]<<" ";
    g<<'\n';
    for(i=1;i<=k;++i) g<<A[i]<<" ";
    g<<'\n';*/
    querry();
    return 0;
}