Cod sursa(job #3174554)

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

using namespace std;

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

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

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

void parcurgere (int start, int p) {
  viz[start] = 1;



  for (int i : g[start]) {
    if (!viz[i]) {
      nivel[start] = p;
      euler[++nr] = start;
      if (!pozitie[start]) {
        pozitie[start] = nr;
      }
      parcurgere(i, p + 1);
    }
  }

  nivel[start] = p;
  euler[++nr] = start;
  if (!pozitie[start]) {
    pozitie[start] = nr;
  }
}

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;
}