Cod sursa(job #1107665)

Utilizator andrei.sfrentSfrent Andrei andrei.sfrent Data 14 februarie 2014 03:16:20
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.42 kb
#include <cstdio>
#include <vector>
#include <utility>
#include <algorithm>

using namespace std;

int N, M;
vector<int> g[100001];
vector<pair<int, int>> E;
pair<int, int> r[20][200010];
int first[100001];

int log2(int n) {
  int p = 1, l = 0;
  while(p <= n) {
    p *= 2;
    l++;
  }
  return l - 1;
}

void read() {
  scanf("%d%d", &N, &M);
  for(int i = 2; i <= N; ++i) {
    int t;
    scanf("%d", &t);
    g[t].push_back(i);
  }
}

void preprocess_rmq() {
  for(int i = 0; i < (int) E.size(); ++i) {
    r[0][i] = E[i];
  }

  int l = log2((int) E.size());
  for(int k = 1; k <= l; ++k) {
    for(int i = 0; i <= (int) E.size() - (1 << k); ++i) {
      int offset = (1 << (k - 1));
      r[k][i] = min(r[k - 1][i], r[k - 1][i + offset]);
    }
  }
}

int solve_query(int a, int b) {
  int k = log2(b - a + 1);
  pair<int, int> res = min(r[k][a], r[k][b - (1 << k) + 1]);
  return res.second;
}


void dfs(int u, int l) {
  first[u] = (int) E.size();
  E.push_back(make_pair(l, u));
  for(int v : g[u]) {
    dfs(v, l + 1);
    E.push_back(make_pair(l, u));
  }
}

void solve() {
  while(M--) {
    int a, b;
    scanf("%d%d", &a, &b);
    int fa = first[a], fb = first[b];
    if(fa > fb) swap(fa, fb);
    int lca = solve_query(fa, fb);
    printf("%d\n", lca);
  }
}

int main(int argc, char *argv[]) {
  freopen("lca.in", "r", stdin);
  freopen("lca.out", "w", stdout);

  read();
  dfs(1, 0);
  preprocess_rmq();
  solve();

  return 0;
}