Cod sursa(job #1547714)

Utilizator spatarelDan-Constantin Spatarel spatarel Data 9 decembrie 2015 19:30:11
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.51 kb
#include <cstdio>
#include <vector>
#include <algorithm>

using std :: min;
using std :: vector;

const int maxN = 100000;

int N;
int father[1 + maxN];
bool viz[1 + maxN];
vector<int> sons[1 + maxN];

int id[1 + maxN], ac;
int euler[maxN << 1], where[1 + maxN], e;

int rmq[20][maxN << 1];
int Log[(maxN << 1) + 1];

void rmqCompute(int v[], int N) {
  for(int i = 0; i < N; ++ i)
    rmq[0][i] = v[i];
  for(int i = 1; (1 << i) <= N; ++ i)
    Log[(1 << i)] = 1;
  for(int i = 1; i <= N; ++ i)
    Log[i] += Log[i - 1];

  int p = 2;
  for(int step = 1; p <= N; ++ step, p <<= 1) {
    int put = p >> 1;
    for(int i = 0; i + put < N; ++ i)
      rmq[step][i] = min(rmq[step - 1][i], rmq[step - 1][i + put]);
  }
}

int rmQuery(int x, int y) {
  int l = y - x + 1;
  int step = Log[l];
  return min(rmq[step][x], rmq[step][y - (1 << step) + 1]);
}


void dfs(int node = 1) {
  if(!viz[node]) {
    viz[node] = true;
    int nodeAc = ac;
    id[ac ++] = node;
    where[node] = e;
    euler[e ++] = nodeAc;
    for (int son: sons[node]) {
      dfs(son);
      euler[e ++] = nodeAc;
    }
  }
}

int lca(int x, int y) {
  x = where[x];
  y = where[y];
  return id[rmQuery(x, y)];
}

int main() {
  freopen("lca.in", "r", stdin);
  freopen("lca.out", "w", stdout);
  int M;
  scanf("%d %d", &N, &M);
  for(int i = 2; i <= N; ++ i) {
    scanf("%d", &father[i]);
    sons[father[i]].push_back(i);
  }

  dfs();
  rmqCompute(euler, e);

  while(M --) {
    int x, y;
    scanf("%d %d", &x, &y);
    printf("%d\n", lca(x, y));
  }
  return 0;
}