Advertisement
tiom4eg

B with DSU+LCA

Dec 14th, 2021
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.49 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. // tiom4eg's precompiler options
  3. // POGGERS POGGERS POGGERS POGGERS POGGERS POGGERS POGGERS
  4. // IO settings
  5. #define fastIO ios_base::sync_with_stdio(false); cin.tie(0)
  6. // Quick types
  7. #define ll long long
  8. #define ld long double
  9. #define ull unsigned long long
  10. #define pii pair <int, int>
  11. #define pll pair <ll, ll>
  12. #define vi vector <int>
  13. #define mi vector <vector <int> >
  14. // Quick functions
  15. #define endl "\n"
  16. #define F first
  17. #define S second
  18. #define all(a) a.begin(), a.end()
  19. #define pb push_back
  20. #define mp make_pair
  21. #define fint(n) int n; cin >> n
  22. #define fstr(s) string s; cin >> s
  23. #define farr(a, n) int a[n]; for (int pog = 0; pog < n; ++pog) cin >> a[pog]
  24. #define min(a, b) ((a < b) ? (a) : (b))
  25. #define max(a, b) ((a > b) ? (a) : (b))
  26. // Quick fors
  27. #define FOR1(s, n) for (int i = s; i < n; ++i)
  28. #define FOR2(s, n) for (int j = s; j < n; ++j)
  29. #define FOR3(s, n) for (int k = s; k < n; ++k)
  30. #define RFOR(n, s) for (int l = n; l >= s; --l)
  31. // Pragmas
  32. #pragma GCC optimize("Ofast") // let the chaos begin!
  33. #pragma GCC optimize ("unroll-loops")
  34. #pragma target("avx,fma")
  35. #pragma comment(linker, "/stack:200000000")
  36. #pragma target("tune=native")
  37. // PBDS
  38. #include <ext/pb_ds/assoc_container.hpp>
  39. #include <ext/pb_ds/tree_policy.hpp>
  40. #define ordered_set tree <int, null_type, less <int>, rb_tree_tag, tree_order_statistics_node_update>
  41. #define ook order_of_key
  42. #define fbo find_by_order
  43. // POGGERS POGGERS POGGERS POGGERS POGGERS POGGERS POGGERS
  44. using namespace std;
  45. using namespace __gnu_pbds;
  46. mt19937 rng(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count());
  47.  
  48. const int MAX = 100005, LOG = 18, INF = 2e9;
  49.  
  50. int p[MAX], h[MAX];
  51.  
  52. // DSU with ranks
  53. int get(int u) {
  54.     if (p[u] == -1) return u;
  55.     return p[u] = get(p[u]);
  56. }
  57.  
  58. bool check(int v, int u) {
  59.     return get(v) == get(u);
  60. }
  61.  
  62. void unite(int v, int u) {
  63.     v = get(v), u = get(u);
  64.     if (h[v] > h[u]) swap(v, u);
  65.     p[v] = u;
  66.     if (h[v] == h[u]) h[u]++;
  67. }
  68.  
  69. // LCA
  70. int l = 1, timer = 0;
  71. vector <pii> g[MAX];
  72. int tin[MAX], tout[MAX];
  73. pii up[MAX][LOG];
  74.  
  75. void dfs(int v, int p = 1, int c = INF) {
  76.     tin[v] = timer++, up[v][0] = {p, c};
  77.     FOR1(1, l + 1) up[v][i] = {up[up[v][i - 1].F][i - 1].F, max(up[v][i - 1].S, up[up[v][i - 1].F][i - 1].S)};
  78.     for (auto& u : g[v]) if (u.F != p) dfs(u.F, v, u.S);
  79.     tout[v] = timer++;
  80. }
  81.  
  82. bool upper(int a, int b) { return tin[a] <= tin[b] && tout[a] >= tout[b]; }
  83.  
  84. int lca(int a, int b) {
  85.     int ans = 0;
  86.     for (int i = l; i >= 0; i--) if (!upper(up[a][i].F, b)) ans = max(ans, up[a][i].S), a = up[a][i].F;
  87.     if (!upper(a, b)) ans = max(ans, up[a][0].S);
  88.     for (int i = l; i >= 0; i--) if (!upper(up[b][i].F, a)) ans = max(ans, up[b][i].S), b = up[b][i].F;
  89.     if (!upper(b, a)) ans = max(ans, up[b][0].S);
  90.     return ans;
  91. }
  92.  
  93. int main() {
  94.     fastIO;
  95.     int n, m, q; cin >> n >> m >> q;
  96.     while ((1 << l) <= n) ++l;
  97.     FOR1(1, n + 1) p[i] = -1, h[i] = 1;
  98.     // Simulate
  99.     FOR1(1, m + 1) {
  100.         int sp = m + 1 - i;
  101.         for (int j = 2; j * sp <= n; ++j) {
  102.             if (!check(sp, j * sp)) {
  103.                 unite(sp, j * sp);
  104.                 g[sp].pb({j * sp, i});
  105.                 g[j * sp].pb({sp, i});
  106.             }
  107.         }
  108.     }
  109.     // Now to answer queries just find maximum on path from A to B
  110.     dfs(1);
  111.     FOR1(0, q) {
  112.         int a, b; cin >> a >> b;
  113.         if (a == b) cout << 0 << endl;
  114.         else cout << lca(a, b) << endl;
  115.     }
  116. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement