Cod sursa(job #2677962)

Utilizator retrogradLucian Bicsi retrograd Data 27 noiembrie 2020 20:55:51
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.97 kb
#ifdef LOCAL
#include <debug.hpp>
#else
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,tune=native")
#define debug(...)
#endif 

#include <bits/stdc++.h>

using namespace std;

struct Lift {
  struct Data { int par, link, dep; };
  vector<Data> T;

  int Add(int par) {
    int ret = T.size();
    if (par == -1) T.push_back(Data{-1, ret, 0});
    else {
      int link = par, a1 = T[par].link, a2 = T[a1].link;
      if (2 * T[a1].dep == T[a2].dep + T[par].dep)
        link = a2;
      T.push_back(Data{par, link, T[par].dep + 1});
    }
    return ret;
  }
  int Kth(int node, int k) {
    int seek = T[node].dep - k;
    if (seek < 0) return -1;
    while (T[node].dep > seek) 
      node = (T[T[node].link].dep >= seek) 
        ? T[node].link : T[node].par;
    return node;
  }
  int LCA(int a, int b) {
    if (T[a].dep < T[b].dep) swap(a, b);
    while (T[a].dep > T[b].dep) 
      a = (T[T[a].link].dep >= T[b].dep) 
        ? T[a].link : T[a].par;
    while (a != b) {
      if (T[a].dep == 0) return -1;
      if (T[a].link != T[b].link) 
        a = T[a].link, b = T[b].link;
      else a = T[a].par, b = T[b].par;
    }
    return a;
  }
};

void DFS(int node, int par, 
    vector<vector<int>>& graph,
    Lift& L, vector<int> &atob, 
    vector<int>& btoa) {
  int nnode = L.Add(par);
  atob[node] = nnode;
  btoa[nnode] = node;
  for (auto vec : graph[node]) 
    DFS(vec, nnode, graph, L, atob, btoa);
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  
  ifstream cin("lca.in");
  ofstream cout("lca.out");

  int n, m; cin >> n >> m;
  vector<vector<int>> graph(n);
  for (int i = 1; i < n; ++i) {
    int par; cin >> par; --par;
    graph[par].push_back(i);
  }
  
  vector<int> atob(n, -1), btoa(n, -1);
  Lift L;
  DFS(0, -1, graph, L, atob, btoa);

  for (int i = 0; i < m; ++i) {
    int a, b; cin >> a >> b; --a; --b;
    cout << 1 + btoa[L.LCA(atob[a], atob[b])] << '\n';
  }
  return 0;
}