Cod sursa(job #2257259)

Utilizator MiricaMateiMirica Matei MiricaMatei Data 9 octombrie 2018 21:11:06
Problema Range minimum query Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.34 kb
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 100000;
const int MAXL = 18;

vector<int>G[MAXN + 5];
int first[MAXN + 5], h[MAXN + 5];
int lin[2 * MAXN + 5];
int p2[2 * MAXN + 5];
int k = 0;

pair<int, int>rmq[MAXL + 1][2 * MAXN + 1];

void dfs(int node) {
  lin[++k] = node;
  first[node] = k;
  for (auto it:G[node]) {
    h[it] = 1 + h[node];
    dfs(it);
    lin[++k] = node;
  }
}

pair<int, int> best(pair<int, int>a, pair<int, int>b) {
  if (a.first < b.first)
    return a;
  return b;
}

pair<int, int> query(int x, int y) {
  int l = y - x + 1;
  int p = p2[l];
  return best(rmq[p][x], rmq[p][y - (1 << p) + 1]);
}

int main() {
  freopen("lca.in","r",stdin);
  freopen("lca.out","w",stdout);

  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 2; i <= n; ++i) {
    int x;
    scanf("%d", &x);
    G[x].push_back(i);
  }

  dfs(1);

  p2[0] = -1;
  for (int i = 1; i <= k; ++i) {
    rmq[0][i] = {h[lin[i]], lin[i]};
    p2[i] = 1 + p2[i >> 1];
  }
  for (int i = 1; i <= MAXL; ++i)
    for (int j = 1; j + (1 << i) <= k; ++j)
      rmq[i][j] = best(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]);

  for (int i = 1; i <= m; ++i) {
    int x, y;
    scanf("%d%d", &x, &y);
    printf("%d\n", query(min(first[x], first[y]), max(first[x], first[y])).second);
  }

  return 0;
}