Mai intai trebuie sa te autentifici.

Cod sursa(job #1542792)

Utilizator cella.florescuCella Florescu cella.florescu Data 5 decembrie 2015 17:37:20
Problema Lowest Common Ancestor Scor 100
Compilator c Status done
Runda Arhiva educationala Marime 1.72 kb
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAXN 100000
#define LIM 8388608

FILE *fin;
char s[LIM];
int p=LIM-1;

void avans(){
  if(++p==LIM){
    fread(s, LIM, 1, fin);
    p=0;
  }
}

int getnr(){
  int nr=0;
  while(isdigit(s[p])==0)
    avans();
  while(isdigit(s[p])){
    nr=nr*10+s[p]-'0';
    avans();
  }
  return nr;
}

int vf[2*MAXN+1], lst[MAXN+1], next[2*MAXN+1], m;
int nod[2*MAXN+1], nivel[2*MAXN+1], prim[MAXN+1], k;

void euler(int x, int niv){
  int p=lst[x];
  nod[++k]=x; prim[x]=k; nivel[k]=niv;
  while(p){
    if(prim[vf[p]]==0){
      euler(vf[p], niv+1);
      nod[++k]=x; nivel[k]=niv;
    }
    p=next[p];
  }
}

void add(int x, int y){
  vf[++m]=y;
  next[m]=lst[x];
  lst[x]=m;
}

int rmq[2*MAXN+1][20], lg[2*MAXN+1];

int main()
{
    FILE *fout;
    int N, M, i, u, v, j, l;
    fin=fopen("lca.in", "r");
    N=getnr(); M=getnr();
    for(i=2; i<=N; i++){
      u=getnr();
      add(i, u); add(u, i);
    }
    euler(1, 0);
    for(i=2; i<=k; i++)
      lg[i]=lg[i>>1]+1;
    for(i=1; i<=k; i++)
      rmq[i][0]=i;
    for(i=1; (1<<i)<=k; i++){
      l=1<<(i-1);
      for(j=1; j<k-(1<<i); j++)
        if(nivel[rmq[j][i-1]]<nivel[rmq[j+l][i-1]])
          rmq[j][i]=rmq[j][i-1];
        else
          rmq[j][i]=rmq[j+l][i-1];
    }
    fout=fopen("lca.out", "w");
    for(i=0; i<M; i++){
      u=prim[getnr()]; v=prim[getnr()];
      if(u>v){
        l=u; u=v; v=l;
      }
      l=lg[v-u+1];
      if(nivel[rmq[u][l]]<nivel[rmq[v-(1<<l)+1][l]])
        fprintf(fout, "%d\n", nod[rmq[u][l]]);
      else
        fprintf(fout, "%d\n", nod[rmq[v-(1<<l)+1][l]]);
    }
    fclose(fin);
    fclose(fout);
    return 0;
}