Cod sursa(job #2282109)

Utilizator Alex.PAlexandru Pacurar Alex.P Data 13 noiembrie 2018 11:09:52
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.62 kb
#include <stdio.h>
#include <stdlib.h>
#include <vector>

using namespace std;

vector <int> v[100001];
int m[20][400001];
int first[100001];
int nivel[400001];
int e[400001];
int log[400001];
int n,euler=1;

int min(int a, int b){
  if(a>b)
      a=b;
  return a;
}

void rmq(){
  int i;
  for(i=1;i<=euler;i++){
    m[0][i] = e[i];
  }
  for(int p=1;(1<<p)<euler;p++){
    for(i=1;i+(1<<p)-1<=euler;i++){
      if(nivel[m[p-1][i]]<nivel[m[p-1][i+(1<<(p-1))]]){
        m[p][i]=m[p-1][i];
      }else{
        m[p][i]=m[p-1][i+(1<<(p-1))];
      }
    }
  }
  log[1]=0;
  for(i=2;i<=euler;i++){
    log[i]=log[i/2]+1;
  }
}

void dfs(int nod, int ni){
  e[euler]=nod;
  if(!first[nod]){
    first[nod]=euler;
    nivel[nod]=ni;
  }
  euler++;
  for(int i=0;i<v[nod].size();i++){
    if(first[v[nod][i]]==0){
      dfs(v[nod][i],ni+1);
      e[euler++]=nod;
    }
  }
}

FILE *fin, *fout;

int lca(int a, int b){
  int i,j;
  i=first[a];
  j=first[b];
  if(j<i){
    int aux=j;
    j=i;
    i=aux;
  }
  if(nivel[m[log[j-i]][i]]<nivel[m[log[j-i]][j-(1<<log[j-i])+1]]){
      fprintf(fout,"%d\n",m[log[j-i]][i]);
    }else{
      fprintf(fout,"%d\n",m[log[j-i]][j-(1<<log[j-i])+1]);
    }
}

int main()
{
    int i,j,x,q;
    fin=fopen("lca.in","r");
    fout=fopen("lca.out","w");
    fscanf(fin,"%d%d",&n,&q);
    for(i=2;i<=n;i++){
      fscanf(fin,"%d",&x);
      v[i].push_back(x);
      v[x].push_back(i);

    }
    dfs(1,0);
    rmq();
    for(q;q>0;q--){
      fscanf(fin,"%d%d",&i,&j);
      lca(i,j);
    }
    fclose(fin);
    fclose(fout);
    return 0;
}