Cod sursa(job #2786685)

Utilizator teochess2017Togan Teodor-Bogdan teochess2017 Data 21 octombrie 2021 15:10:19
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.28 kb
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>

using namespace std;

#define MAXN 100000
#define MAXP2 18

int rmq[MAXN * 2 - 1][MAXP2][2], niveu[2 * MAXN - 1], euler[2 * MAXN - 1], poz[MAXN], log[MAXN * 2 - 1][2];
int ind;

vector <int> mat[MAXN];

void DFS(int el, int niv){
  int i;
  poz[el] = ind;
  euler[ind] = el;
  niveu[ind] = niv;
  ind++;
  for(i = 0; i < mat[el].size(); i++){
    DFS(mat[el][i], niv + 1);
    niveu[ind] = niv;
    euler[ind] = el;
    ind++;
  }
}

int main()
{
    FILE *fin, *fout;
    int n, m, i, j, u, v, p, el, aux;
    fin = fopen("lca.in", "r");
    fscanf(fin, "%d%d", &n, &m);
    for(i = 1; i < n; i++){
      fscanf(fin, "%d", &el);
      mat[el - 1].push_back(i);
    }
    DFS(0, 0);
    for(i = (2 * n - 1) - 1; 0 <= i; i--){
      rmq[i][0][0] = niveu[i];
      rmq[i][0][1] = i;
      ind = 1;//n are vreo semnificatie, doar refolosesc variabila ca sa nu mai fac altele inutil si sa lenumesc stupid:)
      j = i + 1;
      p = 2;
      while(j < (2 * n - 1)){
        if(rmq[i][ind - 1][0] < rmq[j - p / 2 + 1][ind - 1][0]){
          rmq[i][ind][0] = rmq[i][ind - 1][0];
          rmq[i][ind][1] = rmq[i][ind - 1][1];
        }else{
          rmq[i][ind][0] = rmq[j - p / 2 + 1][ind - 1][0];
          rmq[i][ind][1] = rmq[j - p / 2 + 1][ind - 1][1];
        }
        j += p;
        p *= 2;
        ind++;
      }
    }
    p = 1;
    j = 0;
    while(p < (2 * n - 1)){
      log[p - 1][0] = p;
      log[p - 1][1] = j;
      p *= 2;
      j++;
    }
    for(i = 1; i < (2 * n - 1); i++){
      if(log[i][0] == 0){
        log[i][0] = log[i - 1][0];
        log[i][1] = log[i - 1][1];
      }
    }
    fout = fopen("lca.out", "w");
    for(i = 0; i < m; i++){
      fscanf(fin, "%d%d", &u, &v);
      if(poz[v - 1] < poz[u - 1]){
        aux = u;
        u = v;
        v = aux;
      }
      p = log[poz[v - 1] - poz[u - 1]][0];
      j = log[poz[v - 1] - poz[u - 1]][1];
      if(rmq[poz[u - 1]][j][0] < rmq[poz[v - 1] - p + 1][j][0]){
        fprintf(fout, "%d\n", euler[rmq[poz[u - 1]][j][1]] + 1);
      }else{
        fprintf(fout, "%d\n", euler[rmq[poz[v - 1] - p + 1][j][1]] + 1);
      }
    }
    fclose(fin);
    fclose(fout);
    return 0;
}