Mai intai trebuie sa te autentifici.

Cod sursa(job #2731143)

Utilizator FunnyStockyMihnea Andreescu FunnyStocky Data 27 martie 2021 13:08:13
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.92 kb
#include <cstdio>
#include <iostream>
#include <vector>

using namespace std;

const int N = (int) 2e5 + 7;
int n;
int p[N];
int dep[N];
int euler_tour[2 * N];
int tour_sz;
int first_time_on_tour[N];
int last_time_on_tour[N];
int lg2[2 * N];
vector<int> g[N];

int best(int i, int j) {
  if (dep[i] < dep[j]) return i;
  return j;
}

int t[4 * 2 * N];

void build(int v, int tl, int tr) {
  if (tl == tr) {
    t[v] = euler_tour[tl];
  } else {
    int tm = (tl + tr) / 2;
    build(2 * v, tl, tm);
    build(2 * v + 1, tm + 1, tr);
    t[v] = best(t[2 * v], t[2 * v + 1]);
  }
}

int get(int v, int tl, int tr, int l, int r) {
  if (l <= tl && tr <= r) {
    return t[v];
  }
  int tm = (tl + tr) / 2;
  if (r <= tm) return get(2 * v, tl, tm, l, r);
  if (tm + 1 <= l) return get(2 * v + 1, tm + 1, tr, l, r);
  return best(get(2 * v, tl, tm, l, r), get(2 * v + 1, tm + 1, tr, l, r));
}

int get(int l, int r) {
  return get(1, 1, tour_sz, l, r);
}

void dfs_lca(int a) {
  euler_tour[++tour_sz] = a;
  first_time_on_tour[a] = last_time_on_tour[a] = tour_sz;
  for (auto &b : g[a]) {
    dep[b] = 1 + dep[a];
    dfs_lca(b);
    euler_tour[++tour_sz] = a;
    last_time_on_tour[a] = tour_sz;
  }
}

void lcaTM_MihneaAndreescuIntaiDeLaBucuresti() {
  dfs_lca(1);
  for (int i = 2; i <= tour_sz; i++) {
    lg2[i] = 1 + lg2[i / 2];
  }
  build(1, 1, tour_sz);
}

int lca(int a, int b) {
  if (first_time_on_tour[a] > last_time_on_tour[b]) {
    swap(a, b);
  }
  return get(first_time_on_tour[a], last_time_on_tour[b]);
}

int main() {
  freopen ("lca.in", "r", stdin);
  freopen ("lca.out", "w", stdout);
  scanf("%d", &n);
  int q;
  scanf("%d", &q);
  for (int i = 2; i <= n; i++) {
    scanf("%d", &p[i]);
    g[p[i]].push_back(i);
  }
  lcaTM_MihneaAndreescuIntaiDeLaBucuresti();
  while (q--) {
    int a, b;
    scanf("%d %d", &a, &b);
    printf("%d\n", lca(a, b));
  }
}