Cod sursa(job #3157522)

Utilizator victorzarzuZarzu Victor victorzarzu Data 15 octombrie 2023 17:41:42
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.27 kb
#include <bits/stdc++.h>

using namespace std;

#define oo 0x3f3f3f3f

ifstream f("lca.in");
ofstream g("lca.out");

int n, m;
int p[20][100001], lvl[1000001];
vector<int> graph[100001];

void read() {
  f>>n>>m;
  for(int i = 2;i <= n;++i) {
    f>>p[0][i];
    graph[p[0][i]].push_back(i);
  }

  for(int j = 1;(1 << j) <= n;++j) {
    for(int i = 1;i <= n;++i) {
      p[j][i] = p[j - 1][p[j - 1][i]];
    }
  }
}

void dfs(int node, int level) {
  lvl[node] = level;
  for(const auto& ngh : graph[node]) {
    if(!lvl[ngh]) {
      dfs(ngh, level + 1);
    }
  }
}

int lca(int x, int y) {
  if(lvl[x] < lvl[y]) {
    int temp = x;
    x = y;
    y = temp;
  }

  int logx, logy;
  for(logx = 0;(1 << logx) <= lvl[x];++logx);
  for(logy = 0;(1 << logy) <= lvl[y];++logy);

  for(int i = logx;i >= 0;--i) {
    if(lvl[x] - (1 << i) >= lvl[y]) {
      x = p[i][x];
    }
  }

  if(x == y) {
    return x;
  }

  for(int i = logy;i >= 0;--i) {
    if(p[i][x] && p[i][x] != p[i][y]) {
      x = p[i][x];
      y = p[i][y];
    }
  }

  return p[0][x];
}

void solve() {
  dfs(1, 1);
  int x, y;
  for(int i = 1;i <= m;++i) {
    f>>x>>y;
    g<<lca(x, y)<<'\n';
  }
}

int main() {
  read();
  solve();

  return 0;
}