Cod sursa(job #1150811)

Utilizator DeclinGogonea Andrei Declin Data 23 martie 2014 16:06:02
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.45 kb
#include <cstdio>
#include <cmath>
using namespace std;
struct nod
{
    int x;
    nod *u;
};
nod *arb[100001];
int a[200001],m[200001][19],poz[100001],ad[100001],nr;
void add(int i,int x)
{
    nod *q=new nod;
    ad[i]=ad[x]+1;
    q->x=i;
    q->u=arb[x];
    arb[x]=q;

}
void eulerizare(int x)
{
    a[nr]=x;
    if (poz[x]==0)
       poz[x]=nr;
    ++nr;
    while(arb[x]!=NULL)
    {
        eulerizare(arb[x]->x);
        a[nr]=x;
        ++nr;
        arb[x]=arb[x]->u;
    }

}
void rmq()
{
    short j;
    int i,r1,r2;
    for(i=0;i<nr;++i)
    m[i][0]=i;
    for(j=1;1<<j<nr;++j)
    {
        r1=1 << j;
        r2=r1 >> 1;
        for(i=0;i + r1 - 1 <nr;++i)
        if(ad[a[m[i][j-1]]]<=ad[a[m[i + r2 ][j-1]]]) m[i][j]=m[i][j-1];
        else m[i][j]=m[i+r2][j-1];
    }
}
int lca(int x,int y)
{
  int r;
  if (x>y)
  {
      r=x;
      x=y;
      y=r;
  }
  int k =ilogb(y-x);
  r=y-(1<<k);
  if(ad[a[m[x][k]]]<=ad[a[m[r][k]]]) return a[m[x][k]];
  return a[m[r][k]];
}
int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    int n,m,i,x,y;
    scanf("%d%d",&n,&m);
    ad[1]=0;
    for(i=2;i<=n;++i)
    {
        scanf("%d",&x);
        add(i,x);
    }
    eulerizare(1);
    rmq();
    while(m!=0)
    {
        scanf("%d%d",&x,&y);
        if(x==y) printf("%d\n",x);
        else printf("%d\n",lca(poz[y],poz[x]));
        --m;
    }
    return 0;
}