Cod sursa(job #2016008)

Utilizator preda.andreiPreda Andrei preda.andrei Data 28 august 2017 13:53:22
Problema Lowest Common Ancestor Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 2.02 kb
#include <fstream>
#include <vector>

using namespace std;

struct Node
{
  int time = 0;
  vector<int> sons;
  vector<int> ancestors;
};

using Tree = vector<Node>;

const int kBuffCap = (1 << 16);

ifstream fin("lca.in");
ofstream fout("lca.out");

char NextChar()
{
  static char buffer[kBuffCap];
  static int buff_size = 0;
  static int buff_index = kBuffCap;

  if (buff_index >= buff_size) {
    fin.read(buffer, kBuffCap);
    buff_size = fin.gcount();
    buff_index = 0;
  }
  return buffer[buff_index++];
}

int NextInt()
{
  char ch;
  do {
    ch = NextChar();
  } while (ch < '0' || ch > '9');

  int num = 0;
  while (ch >= '0' && ch <= '9') {
    num = num * 10 + ch - '0';
    ch = NextChar();
  }
  return num;
}

void Dfs(Tree &t, int node)
{
  if (!t[node].ancestors.empty()) {
    int father = t[node].ancestors[0];
    int order = 0;

    while (order < (int)t[father].ancestors.size()) {
      int anc = t[father].ancestors[order];
      t[node].ancestors.push_back(anc);
      father = anc;
      order += 1;
    }
  }

  for (const auto &son : t[node].sons) {
    Dfs(t, son);
  }

  static int time = 0;
  t[node].time = ++time;
}

int FindLca(const Tree &t, int a, int b)
{
  if (t[a].time > t[b].time) {
    swap(a, b);
  }

  while (t[a].time < t[b].time) {
    if (t[a].ancestors.size() == 1) {
      a = t[a].ancestors[0];
    }

    for (size_t i = 1; i < t[a].ancestors.size(); ++i) {
      int anc = t[a].ancestors[i];
      if (t[anc].time > t[b].time) {
        a = t[a].ancestors[i - 1];
        break;
      } else if (i + 1 == t[a].ancestors.size()) {
        a = t[a].ancestors.back();
      }
    }
  }
  return a;
}

int main()
{
  int nodes = NextInt();
  int q = NextInt();

  Tree tree(nodes);
  for (int i = 1; i < nodes; ++i) {
    int father = NextInt();
    tree[i].ancestors.push_back(father - 1);
    tree[father - 1].sons.push_back(i);
  }

  Dfs(tree, 0);

  while (q--) {
    int a = NextInt();
    int b = NextInt();

    auto res = FindLca(tree, a - 1, b - 1);
    fout << res + 1 << "\n";
  }
  return 0;
}