Cod sursa(job #1218285)

Utilizator DjokValeriu Motroi Djok Data 10 august 2014 13:05:42
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.18 kb
#include<fstream>
#include<algorithm>
using namespace std;

typedef struct lnod {
      int info;
      lnod *next;
}*nod;

int e[200005],h[200005],lg[200005],rmq[20][100005],poz[100005];
int nr,x,y,gmb,fnc,dif,l,sh,rs,m,n,i;
nod lda[100005];

void add(int x,nod &y) {
    nod p=new lnod;
    p->info=x;
    p->next=y;
    y=p;
}

void dfs(int x,int niv) {
   h[++nr]=niv; e[nr]=x; poz[x]=nr;
   for(nod p=lda[x];p;p=p->next)
   dfs(p->info,niv+1),h[++nr]=niv,e[nr]=x;
}

void RMQ() {
  int i,j,l;
  for(rmq[0][1]=1,i=2;i<=nr;++i)
  lg[i]=lg[i/2]+1,rmq[0][i]=i;

  for(i=1;(1<<i)<nr;++i)
    for(j=1;j+(1<<i)<nr;++j)
    {
      l=1<<(i-1);
      rmq[i][j]=rmq[i-1][j];
      if(h[rmq[i-1][j+l]]<h[rmq[i][j]])
      rmq[i][j]=rmq[i-1][j+l];
    }
}

int main()
{
  ifstream cin("lca.in");
  ofstream cout("lca.out");

  cin>>n>>m;
  for(i=2;i<=n;++i) cin>>x,add(i,lda[x]);

  dfs(1,0); RMQ();

  while(m--)
  {
    cin>>x>>y;
    gmb=poz[x]; fnc=poz[y];
    if(gmb>fnc) swap(gmb,fnc);

    dif=fnc-gmb+1; l=lg[dif];
    sh=dif-(1<<l); rs=rmq[l][gmb];
    if(h[rs]>h[rmq[l][sh+gmb]]) rs=rmq[l][sh+gmb];

    cout<<e[rs]<<'\n';
  }

 return 0;
}