Cod sursa(job #2886950)

Utilizator iraresmihaiiordache rares mihai iraresmihai Data 8 aprilie 2022 17:12:29
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.21 kb
#include <iostream>
#include <vector>

#define MAXN 100000
#define MAX_LOG 19
using namespace std;

struct node{
  int lvl;
  bool visited;
  vector <int> children;
};

struct elem{
  int val;
  int pos;
};

node tree[MAXN + 1];
int lvl[MAXN + 1];
int firstApp[MAXN + 1];
int euler[MAXN * 2];
int eulerSize;
int logg[MAXN * 2];
elem rmq[MAXN * 2][MAX_LOG];

void dfs(int pos, int level) {
  tree[pos].visited = true;
  firstApp[pos] = eulerSize;
  euler[eulerSize] = pos;
  lvl[pos] = level;
  eulerSize++;

  for ( int i : tree[pos].children ) {
    if ( !tree[i].visited ) {
      dfs(i, level + 1);
      euler[eulerSize] = pos;
      eulerSize++;
    }
  }
}

void precalcLog(int n) {
  int i;

  for ( i = 2; i <= n; i++ ) {
    logg[i] = logg[i / 2] + 1;
  }

}

void buildRmq(int n) {
  int i, i2;

  for ( i = 1; i <= n; i++ ) {
    rmq[i][0].pos = euler[i];
    rmq[i][0].val = lvl[euler[i]];
  }

  for ( i = 1; i <= logg[n]; i++ ) {
    for ( i2 = 1; i2 + (1 << i) - 1 <= n; i2++ ) {
      if ( rmq[i2][i - 1].val < rmq[i2 + (1 << (i - 1))][i - 1].val ) {
        rmq[i2][i].val = rmq[i2][i - 1].val;
        rmq[i2][i].pos = rmq[i2][i - 1].pos;
      } else {
        rmq[i2][i].val = rmq[i2 + (1 << (i - 1))][i - 1].val;
        rmq[i2][i].pos = rmq[i2 + (1 << (i - 1))][i - 1].pos;
      }
    }
  }
}

int query(int a, int b) {
  int st, dr, lenght;

  st = firstApp[a];
  dr = firstApp[b];

  if ( st > dr )
    swap(st, dr);

  lenght = dr - st + 1;
  if ( rmq[st][logg[lenght]].val < rmq[dr - (1 << logg[lenght]) + 1][logg[lenght]].val )
    return rmq[st][logg[lenght]].pos;
  return rmq[dr - (1 << logg[lenght]) + 1][logg[lenght]].pos;
}

int main() {
  FILE *fin, *fout;
  fin = fopen("lca.in", "r");
  fout = fopen("lca.out", "w");

  int n, t, i, a, b;

  fscanf(fin, "%d%d", &n, &t);

  for ( i = 2; i <= n; i++ ) {
    fscanf(fin, "%d", &a);
    tree[a].children.push_back(i);
  }

  eulerSize = 1;

  dfs(1, 0);
  eulerSize--;
  precalcLog(eulerSize);
  buildRmq(eulerSize);

  while ( t-- ) {
    fscanf(fin, "%d%d", &a, &b);

    fprintf(fout, "%d\n", query(a, b));
  }

  fclose(fin);
  fclose(fout);

  return 0;
}