Advertisement
Z_Michael

Timus 2109

Apr 8th, 2020
188
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.27 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. using namespace std;
  5. int ras = 200010, n, l, timer, q;
  6.  
  7. vector <int> tin, tout, h, aga, tree;
  8. vector <vector <int>> grafs, up;
  9.  
  10.  
  11. void dfs(int v, int p = 1, int hh = 0) {
  12.     tin[v] = ++timer;
  13.     h[v] = hh;
  14.     up[v][0] = p;
  15.     for (int i = 1; i <= l; i++) {
  16.         up[v][i] = up[up[v][i - 1]][i - 1];
  17.     }
  18.  
  19.     for (int i = 0; i < grafs[v].size(); i++) {
  20.         int to = grafs[v][i];
  21.         if (to != p) {
  22.             dfs(to, v, hh + 1);
  23.         }
  24.     }
  25.  
  26.     tout[v] = ++timer;
  27. }
  28.  
  29. bool upper(int a, int b) {
  30.     return tin[a] <= tin[b] && tout[a] >= tout[b];
  31. }
  32.  
  33. int lca(int a, int b) {
  34.     if (upper(a, b))  return a;
  35.     if (upper(b, a))  return b;
  36.     for (int i = l; i >= 0; i--)
  37.         if (!upper(up[a][i], b))
  38.             a = up[a][i];
  39.     return up[a][0];
  40. }
  41.  
  42. void build(int pos, int beg, int end) {
  43.     if (beg == end) {
  44.         tree[pos] = aga[beg];
  45.     }
  46.     else {
  47.         int prom = (beg + end) / 2;
  48.         build(2 * pos, beg, prom);
  49.         build(2 * pos + 1, prom + 1, end);
  50.         if (h[tree[2 * pos]] < h[tree[2 * pos + 1]]) {
  51.             tree[pos] = tree[2 * pos];
  52.         }
  53.         else {
  54.             tree[pos] = tree[2 * pos + 1];
  55.         }
  56.     }
  57. }
  58.  
  59. int minim(int pos, int beg, int end, int l, int r) {
  60.     if (l > r) {
  61.         return 0;
  62.     }
  63.     if (beg == l && end == r) {
  64.         return tree[pos];
  65.     }
  66.  
  67.     int prom = (beg + end) / 2;
  68.     int k1 = minim(2 * pos, beg, prom, l, min(r, prom));
  69.     int k2 = minim(2 * pos + 1, prom + 1, end, max(prom + 1, l), r);
  70.     if (h[k1] < h[k2]) {
  71.         return k1;
  72.     }
  73.     else {
  74.         return k2;
  75.     }
  76. }
  77.  
  78.  
  79. int main()
  80. {
  81.     iostream::sync_with_stdio(false);
  82.     cin.tie(0), cout.tie(0);
  83.     cin >> n;
  84.  
  85.     grafs.resize(n + 1); tin.resize(n + 1); tout.resize(n + 1); up.resize(n + 1); h.resize(n + 1); aga.resize(n + 1), tree.resize(2000000);
  86.  
  87.     for (int i = 0; i < (n - 1); i++) {
  88.         int fr, to;
  89.  
  90.         cin >> fr >> to;
  91.  
  92.         grafs[fr].push_back(to);
  93.         grafs[to].push_back(fr);
  94.     }
  95.  
  96.     l = 0;
  97.     int y = n;
  98.     while (y > 0) {
  99.         l++;
  100.         y /= 2;
  101.     }
  102.  
  103.     for (int i = 0; i <= n; i++) {
  104.         up[i].resize(l + 1);
  105.     }
  106.  
  107.     dfs(1, 1, 0);
  108.     cin >> q;
  109.     h[0] = n + 1;
  110.     for (int i = 1; i < n; i++) {
  111.         aga[i] = lca(i, i + 1);
  112.     }
  113.     if (n > 1) {
  114.         build(1, 1, n - 1);
  115.     }
  116.  
  117.     for (int i = 0; i < q; i++) {
  118.         int a, b;
  119.         cin >> a >> b;
  120.         if (a != b) {
  121.             cout << minim(1, 1, n - 1, a, b - 1) << "\n";
  122.         }
  123.         else {
  124.             cout << a << "\n";
  125.         }
  126.     }
  127. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement