Cod sursa(job #1930173)

Utilizator stoianmihailStoian Mihail stoianmihail Data 18 martie 2017 16:10:52
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.81 kb
#include <stdio.h>

#define MAX_N 100000
#define MAX_LOG 16

typedef struct {
  int v, next;
} list;

int N, M, tmp;
int time, buff;
int h[MAX_N + 1];
int adj[MAX_N + 1];
list l[MAX_N];
int rmq[MAX_LOG + 1][(MAX_N << 1) + 1];
int lg[(MAX_N << 1) + 1];
int ptr[MAX_N + 1];

void addEdge(int u, int v) {
  buff++;
  l[buff].next = adj[u];
  l[buff].v = v;
  adj[u] = buff;
}

void dfs(int u) {
  int pos, v;
  for (pos = adj[u]; pos; pos = l[pos].next) {
    v = l[pos].v;
    rmq[0][++time] = u;
    ptr[u] = time;
    h[v] = h[u] + 1;
    dfs(v);
  }
  if (adj[u] == 0) {
    rmq[0][++time] = u;
    ptr[u] = time;
  }
}

int get(int u, int v) {
  if (ptr[v] < ptr[u]) {
    tmp = u;
    u = v;
    v = tmp;
  }
  tmp = lg[ptr[v] - ptr[u]];
  if (h[rmq[tmp][ptr[u]]] < h[rmq[tmp][ptr[v] - (1 << tmp) + 1]]) {
    return rmq[tmp][ptr[u]];
  }
  return rmq[tmp][ptr[v] - (1 << tmp) + 1];
}

int main(void) {
  int u, v, i;
  FILE *f = fopen("lca.in", "r");

  fscanf(f, "%d %d", &N, &M);
  for (u = 2; u <= N; u++) {
    fscanf(f, "%d", &v);
    addEdge(v, u);
  }

  dfs(1);

  for (i = 1; i <= time; i++) {
    fprintf(stderr, "(%d, %d) ", rmq[0][i], h[rmq[0][i]]);
  }
  fprintf(stderr, "\n");

  lg[1] = 0;
  for (i = 2; i <= time; i++) {
    lg[i] = lg[i >> 1] + 1;
  }
  for (i = 1; i <= MAX_LOG; i++) {
    for (u = 1; u <= time; u++) {
      if (h[rmq[i - 1][u]] < h[rmq[i - 1][u + (1 << (i - 1))]]) {
        rmq[i][u] = rmq[i - 1][u];
      } else {
        rmq[i][u] = rmq[i - 1][u + (1 << (i - 1))];
      }
    }
  }
  freopen("lca.out", "w", stdout);
  while (M) {
    fscanf(f, "%d %d", &u, &v);
    fprintf(stderr, "%d %d\n", ptr[u], ptr[v]);
    fprintf(stdout, "%d\n", get(u, v));
    M--;
  }
  fclose(f);
  fclose(stdout);
  return 0;
}