Cod sursa(job #2752574)

Utilizator Razvan48Capatina Razvan Nicolae Razvan48 Data 18 mai 2021 16:58:57
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.37 kb
#include <fstream>
#include <vector>

using namespace std;

struct Query
{
  int tip;

  int x;
  int y;

  Query() {};

  Query(int tip, int x, int y) :
    tip(tip), x(x), y(y) {};
};

const int NMAX = 100000;
const int MMAX = 100000;
const int GRAPH_MAX = NMAX + MMAX;
const int LOG_MAX = 18;

vector<int> graf[1 + GRAPH_MAX];

Query query[1 + MMAX];

vector<int> preOrdine;
vector<int> euler;

int posEuler[1 + GRAPH_MAX];

int h[1 + GRAPH_MAX];

pair<int, int> rmq[2 * GRAPH_MAX - 1][1 + LOG_MAX];

int log[2 * GRAPH_MAX];

void dfs(int nod, int tata)
{
  h[nod] = h[tata] + 1;

  preOrdine.push_back(nod);
  euler.push_back(nod);
  posEuler[nod] = euler.size() - 1;

  for (auto& fiu : graf[nod])
  {
    if (fiu != tata)
    {
      dfs(fiu, nod);
      euler.push_back(nod);
    }
  }
}

void calcRmq()
{
  for (int i = 0; i < euler.size(); i++)
  {
    rmq[i][0].first = h[euler[i]];
    rmq[i][0].second = euler[i];
  }

  for (int exp = 1; exp <= LOG_MAX; exp++)
  {
    for (int i = 0; i + (1 << exp) - 1 < euler.size(); i++)
    {
      rmq[i][exp] = min(rmq[i][exp - 1], rmq[i + (1 << (exp - 1))][exp - 1]);
    }
  }

  int putere = 1;
  int exp = 0;

  for (int i = 1; i <= euler.size(); i++)
  {
    if (putere * 2 <= i)
    {
      putere *= 2;
      exp++;
    }

    log[i] = exp;
  }
}

int lca(int a, int b)
{
  int logCalc = log[posEuler[b] - posEuler[a] + 1];

  return min(rmq[posEuler[a]][logCalc], rmq[posEuler[b] - (1 << logCalc) + 1][logCalc]).second;
}

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

  int n, m;
  in >> n >> m;

  /*
  for (int i = 2; i <= n; i++)
  {
    int x, y;
    in >> x >> y;

    graf[x].push_back(y);
    graf[y].push_back(x);
  }

  for (int j = 1; j <= m; j++)
  {
    in >> query[j].tip >> query[j].x;

    if (query[j].tip == 0)
    {
      in >> query[j].y;

      graf[x].push_back(y);
    }
  }
  */

  for (int i = 2; i <= n; i++)
  {
    int x;

    in >> x;

    graf[x].push_back(i);
    graf[i].push_back(x);
  }

  dfs(1, 0);

  calcRmq();

  for (int j = 1; j <= m; j++)
  {
    int a, b;

    in >> a >> b;

    out << lca(a, b) << '\n';
  }

  /*
  for (int j = 1; j <= m; j++)
  {
    if (query[j].tip == 0)
    {
      h[query[j].y] = 0;
    }
  }
  */

  return 0;
}