Cod sursa(job #2635253)

Utilizator k2e0e0w3qDumitrescu Gheorghe k2e0e0w3q Data 13 iulie 2020 20:00:14
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.9 kb
#include <fstream>
#define N 200000
#define log(x) 31 - __builtin_clz(x)
#define B 30
using namespace std;

int n, mask[N], first[N<<1], niv[N<<1],
  seg[log(N/B)+2][N], v[(N<<1)+1], size;

int cmp (int a, int b) {
  return niv[v[a]] < niv[v[b]] ? a : b;
}

int trans (int x, int base = B) {
  return x - (log(mask[x] & ((1 << base) - 1)));
}

int query (int x, int y) {
  if (y - x + 1 <= B)
    return v[trans(y, y-x+1)];
  int ans = cmp(trans(x + B - 1), trans(y));

  x /= B; ++x;
  y /= B; --y;
  if (x <= y) {
    int lg = log(y-x+1);
    ans = cmp(ans, cmp(seg[lg][x], seg[lg][y - (1<<lg) + 1]));
  }
  return v[ans];
}

struct nod {
  int inf;
  struct nod* urm;
} *G[N+1];

void add (int x, int i) {
  struct nod *e = (struct nod*) malloc(sizeof (struct nod));
  e->inf = i;
  e->urm = G[x];

  G[x] = e;
}

void dfs (int x, int from) {
  v[size++] = x;

  for (; G[x]; G[x]=G[x]->urm) {
      first[G[x]->inf] = size;
      dfs(G[x]->inf, x);
    }
  v[size++] = from;
}

int main (void) {
  ifstream fin ("lca.in");
  ofstream fout ("lca.out");

  int q, i, j;
  fin >> n >> q;
  for (i=2; i<=n; ++i) {
    fin >> j;
    niv[i] = niv[j] + 1;
    add(j, i);
  }
  dfs(1, 0);

  n = size;
  int at = 0, ctz;
  for (i=0; i<n; ++i) {
    at = (at << 1) & ((1<<B) - 1);
    ctz = __builtin_ctz(at);
    while (at && cmp(i, i - ctz) == i) {
      at ^= 1 << ctz;
      ctz = __builtin_ctz(at);
    }
    at |= 1;
    mask[i] = at;
  }

  n /= B;
  for (i=0; i<n; ++i)
    seg[0][i] = trans(B*i + B - 1);

  for (i=1; (1<<i) <= n; ++i)
    for (j=0; j + (1<<i) <= n; ++j)
      seg[i][j] = cmp(seg[i-1][j], seg[i-1][j + (1<<i-1)]);

  int x, y;
  for (; q; --q) {
    fin >> x >> y;
    x = first[x];
    y = first[y];

    if (x > y) {
      i = x;
      x = y;
      y = i;
    }

    fout << query(x, y) << '\n';
  }
  return 0;
}