Cod sursa(job #3174544)

Utilizator antoniadutuDutu Antonia antoniadutu Data 24 noiembrie 2023 21:32:04
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.05 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

int n, m, tata[100001], viz[100001], nr, euler[100001], nivel[100001], pozitie[100001];
int minim, raspuns;
vector <int> g[100001];

struct {
  int a, b;
} aint[5000006];

void parcurgere (int start, int p) {
  viz[start] = 1;
  nivel[start] = p;
  euler[++nr] = start;
  pozitie[start] = nr;


  for (int i : g[start]) {
    if (!viz[i]) {

      parcurgere(i, p + 1);
      nr++;
    }

    euler[nr] = start;
    pozitie[start] = nr;
    nivel[start] = p;
  }


}

void build (int nod, int left, int right) {
  if (left == right) {
    aint[nod].a = nivel[euler[left]];
    aint[nod].b = euler[left];

    return;
  }

  int middle = (left + right) / 2;

  build(2 * nod, left, middle);
  build(2 * nod + 1, middle + 1, right);

  if (aint[2 * nod].a < aint[2 * nod + 1].a) {
    aint[nod].a = aint[2 * nod].a;
    aint[nod].b = aint[2 * nod].b;
  } else {
    aint[nod].a = aint[2 * nod + 1].a;
    aint[nod].b = aint[2 * nod + 1]. b;
  }
}

void query (int nod, int left, int right, int stanga, int dreapta) {
  if (stanga <= left && dreapta >= right) {
    if (aint[nod].a  <= minim) {
      minim = aint[nod].a;
      raspuns = aint[nod].b;
    }

    return;
  }

  int middle = (left + right) / 2;

  if (stanga <= middle) {
    query(2 * nod, left, middle, stanga, dreapta);
  }

  if (dreapta > middle) {
    query(2 * nod + 1, middle + 1, right, stanga, dreapta);
  }
}
int main () {

  fin >> n >> m;

  for (int i = 2; i <= n; i++) {
    fin >> tata[i];

    g[i].push_back(tata[i]);
    g[tata[i]].push_back(i);
  }

  parcurgere(1, 1);

  build(1, 1, nr);

  for (int i = 1; i <= m; i++) {
    int x, y;

    fin >> x >> y;

    int ceva_x = pozitie[x];
    int ceva_y = pozitie[y];
    if (ceva_x > ceva_y) {
      swap(ceva_x, ceva_y);
    }

    minim = 1e7;
    raspuns = 0;
    query(1, 1, nr, ceva_x, ceva_y);

    fout << raspuns << '\n';
  }


  return 0;
}