Cod sursa(job #3041384)

Utilizator iraresmihaiiordache rares mihai iraresmihai Data 31 martie 2023 13:39:38
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.81 kb
#include <iostream>
#include <vector>

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

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

node tree[MAXN];
int binaryLift[MAXN][MAX_LOG];
int n;

void dfs(int pos, int lvl) {
  tree[pos].lvl = lvl;
  tree[pos].visited = true;

  for ( int v : tree[pos].neighbours ) {
    if ( !tree[v].visited ) {
      tree[v].parent = pos;
      dfs(v, lvl + 1);
    }
  }
}

void buildBinaryLift() {
  int i, i2;

  for ( i = 0; i < n; i++ ) {
    binaryLift[i][0] = tree[i].parent;
  }

  for ( i = 1; i < MAX_LOG; i++ ) {
    for ( i2 = 0; i2 < n; i2++ ) {
      binaryLift[i2][i] = binaryLift[binaryLift[i2][i - 1]][i - 1];
    }
  }
}

int lca(int a, int b) {
  int i;

  if ( tree[a].lvl < tree[b].lvl ) {
    swap(a, b);
  } ///tree[a].lvl = max

  for ( i = MAX_LOG - 1; i >= 0; i-- ) {
    if ( tree[a].lvl - (1 << i) >= tree[b].lvl ) {
      a = binaryLift[a][i];
    }
  }

  if ( a != b ) {
    for ( i = MAX_LOG - 1; i >= 0; i-- ) {
      if ( binaryLift[a][i] != binaryLift[b][i] ) {
        a = binaryLift[a][i];
        b = binaryLift[b][i];
      }
    }

    a = binaryLift[a][0];
  }

  return a;
}

void addEdge(int a, int b) {
  tree[a].neighbours.push_back(b);
  tree[b].neighbours.push_back(a);
}

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

  int i, a, b, q;

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

  for ( i = 1; i < n; i++ ) {
    fscanf(fin, "%d", &a);

    a--;

    addEdge(a, i);
  }


  dfs(0, 1);
  buildBinaryLift();


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

    fprintf(fout, "%d\n", lca(a, b) + 1);
  }

  fclose(fin);
  fclose(fout);

  return 0;
}