Cod sursa(job #1801489)

Utilizator andrei_diaconu11Andrei C. Diaconu andrei_diaconu11 Data 9 noiembrie 2016 08:07:13
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.32 kb
#include <stdio.h>
#define MAXN 100000
int ult[MAXN+1], ad[MAXN+1], next[MAXN+1], poz=0, eu[2*MAXN+1], niv[2*MAXN+1], rmq[2*MAXN+1][18], log[2*MAXN+1], pr[MAXN+1];
bool viz[MAXN+1];
void adauga(int a, int b){//b fiu al lui a
  ad[++poz]=b;
  next[poz]=ult[a];
  ult[a]=poz;
}

void euler(int nod, int n){
  eu[++poz]=nod;
  niv[poz]=n;
  int i=ult[nod];
  while(i!=0){
    euler(ad[i],n+1);
    eu[++poz]=nod;
    niv[poz]=n;
    i=next[i];
  }
}

inline int calc(int a, int b, int c){
  if(niv[rmq[a][c]]<niv[rmq[b][c]])
    return rmq[a][c];
  return rmq[b][c];
}

inline void swap(int &a, int &b){
  int aux;
  aux=a;
  a=b;
  b=aux;
}

int main()
{
  int n, m, i, j, x, k, a, b;
  FILE *fi=fopen("lca.in", "r"), *fo=fopen("lca.out", "w");
  fscanf(fi, "%d%d", &n, &m);
  for(i=2;i<=n;i++){
    fscanf(fi, "%d", &x);
    adauga(x,i);
  }
  poz=0;
  euler(1,1);
  k=2*n-1;
  for(i=1;i<=k;i++)
    for(j=0;(1<<j)<=i;j++){
      if(j==0){
        rmq[i][j]=i;
        if(pr[eu[i]]==0)
          pr[eu[i]]=i;
      }
      else
        rmq[i][j]=calc(i,i-(1<<(j-1)),j-1);
    }
  log[1]=0;
  for(i=2;i<=k;i++)
    log[i]=1+log[i/2];
  for(i=0;i<m;i++){
    fscanf(fi, "%d%d", &a, &b);
    a=pr[a];
    b=pr[b];
    if(a>b) swap(a,b);
    fprintf(fo, "%d\n", eu[calc(b,a+(1<<log[b-a+1])-1,log[b-a+1])]);
  }
  fclose(fi);
  fclose(fo);
  return 0;
}