fork download
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. typedef long long ll;
  6. typedef pair<int, int> ii;
  7.  
  8. const int INF = 1e9;
  9. const ll LINF = 1e18;
  10.  
  11. const int N = 2e5 + 5;
  12. const int LOG = 18;
  13.  
  14. int n, q;
  15. vector<int> adj[N];
  16.  
  17. int up[LOG][N]; // up[i][u] = Tổ tiên thứ 2^i của u
  18. int tin[N]; // tin[u] = Thời gian dfs đi vào đỉnh u
  19. int tout[N]; // tout[u] = Thời gian dfs đi ra khỏi đỉnh u
  20. int timer;
  21.  
  22. void dfs(int u, int p) {
  23. tin[u] = ++timer;
  24.  
  25. up[0][u] = p;
  26. for (int i = 1; i < LOG; i++) {
  27. up[i][u] = up[i - 1][up[i - 1][u]];
  28. }
  29.  
  30. for (int v : adj[u]) {
  31. if (v == p) continue;
  32. dfs(v, u);
  33. }
  34.  
  35. tout[u] = timer;
  36. }
  37.  
  38. // Kiểm tra u có phải tổ tiên của v
  39. bool isAncestor(int u, int v) {
  40. return (tin[u] <= tin[v] && tout[v] <= tout[u]);
  41. }
  42.  
  43. // LCA (Lowest Common Ancestor) - Tổ tiên chung gần nhất của u và v
  44. int lca(int u, int v) {
  45. if (isAncestor(u, v)) return u;
  46. if (isAncestor(v, u)) return v;
  47.  
  48. for (int i = LOG - 1; i >= 0; i--) {
  49. if (!isAncestor(up[i][u], v)) {
  50. u = up[i][u];
  51. }
  52. }
  53. return up[0][u];
  54. }
  55.  
  56. int main() {
  57. ios::sync_with_stdio(false);
  58. cin.tie(nullptr);
  59. cin >> n >> q;
  60.  
  61. for (int u = 2; u <= n; u++) {
  62. int p; cin >> p;
  63. adj[u].push_back(p);
  64. adj[p].push_back(u);
  65. }
  66.  
  67. timer = 0;
  68. dfs(1, 1);
  69.  
  70. while (q--) {
  71. int u, v;
  72. cin >> u >> v;
  73. cout << lca(u, v) << '\n';
  74. }
  75. }
Success #stdin #stdout 0.01s 22248KB
stdin
5 3
1 1 3 3
4 5
2 5
1 4
stdout
3
1
1