Cod sursa(job #3216268)

Utilizator mihaipriboimihailucapriboi mihaipriboi Data 15 martie 2024 19:30:46
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.36 kb
// Mihai Priboi

#include <stdio.h>
#include <vector>

using namespace std;

struct node {
  int p, jump, depth;
};

#define MAX_N 100000

node gf[MAX_N + 1];

vector<int> adj[MAX_N + 1];

void dfs(int u) {
  int v1 = gf[u].jump;
  int v2 = gf[v1].jump;
  bool eq = (gf[v1].depth - gf[u].depth) == (gf[v2].depth - gf[v1].depth);

  for (auto v : adj[u]) {
    gf[v].depth = gf[u].depth + 1;
    gf[v].jump = eq ? v2 : u;

    dfs(v);
  }
}

int main() {
  FILE *fin, *fout;
  int n, m, i;

  fin = fopen("lca.in", "r");
  fout = fopen("lca.out", "w");
  
  fscanf(fin, "%d%d", &n, &m);
  for (i = 2; i <= n; i++) {
    int u;
    fscanf(fin, "%d", &u);
    gf[i].p = u;
    adj[u].push_back(i);
  }

  gf[0].jump = gf[1].jump = 1;
  gf[0].depth = gf[1].depth = 0;

  dfs(1);

  for (i = 0; i < m; i++) {
    int u, v;
    fscanf(fin, "%d%d", &u, &v);

    if (gf[u].depth < gf[v].depth)
      swap(u, v);

    while (gf[u].depth > gf[v].depth) {
      if (gf[gf[u].jump].depth >= gf[v].depth)
        u = gf[u].jump;
      else
        u = gf[u].p;
    }

    while (u != v) {
      if (gf[u].jump != gf[v].jump) {
        u = gf[u].jump;
        v = gf[v].jump;
      } else {
        u = gf[u].p;
        v = gf[v].p;
      }
    }

    fprintf(fout, "%d\n", u);
  }

  fclose(fin);
  fclose(fout);
  return 0;
}