Cod sursa(job #2440803)

Utilizator lucametehauDart Monkey lucametehau Data 19 iulie 2019 13:27:15
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.52 kb
#include <fstream>
#include <vector>

using namespace std;

ifstream cin ("lca.in");
ofstream cout ("lca.out");

int n, q, m, x, y;

vector <int> euler, g[100005];
int seg[2000005], depth[100005], fst[100005];
bool viz[100005];

void dfs(int nod, int d) {
  viz[nod] = 1;
  depth[nod] = d;
  fst[nod] = euler.size();
  euler.push_back(nod);
  for(auto &son : g[nod]) {
    if(!viz[son]) {
      dfs(son, d + 1);
      euler.push_back(nod);
    }
  }
}

void build(int nod, int l, int r) {
  if(l == r) {
    seg[nod] = euler[l];
    return;
  }
  int mid = (l + r) >> 1;
  build(2 * nod, l, mid);
  build(2 * nod + 1, mid + 1, r);
  int ln = seg[2 * nod], rn = seg[2 * nod + 1];
  seg[nod] = (depth[ln] < depth[rn] ? ln : rn);
}

int query(int nod, int l, int r, int st, int dr) {
  if(dr < l || r < st)
    return -1;
  if(st <= l && r <= dr)
    return seg[nod];
  int mid = (l + r) >> 1, ln = query(2 * nod, l, mid, st, dr), rn = query(2 * nod + 1, mid + 1, r, st, dr);
  if(ln == -1)
    return rn;
  if(rn == -1)
    return ln;
  return (depth[ln] < depth[rn] ? ln : rn);
}

int lca(int x, int y) {
  int l = fst[x], r = fst[y];
  if(l > r)
    swap(l, r);
  return query(1, 0, euler.size() - 1, l, r);
}

int main() {
  cin >> n >> q;
  for(int i = 1; i < n; i++) {
    cin >> x, x--;
    g[i].push_back(x);
    g[x].push_back(i);
  }
  dfs(0, 0);
  build(1, 0, euler.size() - 1);
  for(; q; q--) {
    cin >> x >> y, x--, y--;
    cout << lca(x, y) + 1 << "\n";
  }
  return 0;
}