bingxuan9112

APIO 2020 swap

Aug 17th, 2020
2,217
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.21 KB | None | 0 0
  1. #include "swap.h"
  2.  
  3. #include <bits/stdc++.h>
  4. #ifdef local
  5. #define debug(...) qqbx(#__VA_ARGS__, __VA_ARGS__)
  6. #define safe cerr<<__PRETTY_FUNCTION__<<" line "<<__LINE__<<" safe\n"
  7. void qqbx(const char *s) {s;}
  8. template <typename H, typename ...T> void qqbx(const char *s, const H &h, T ...args) {
  9.     for(; *s && *s != ','; ++s) if(*s != ' ') std::cerr << *s;
  10.     std::cerr << " = " << h << (sizeof...(T) ? ", " : "\n");
  11.     if(sizeof...(T)) qqbx(++s, args...);
  12. }
  13. #else
  14. #define debug(...) ((void)0)
  15. #define safe ((void)0)
  16. #endif // local
  17. #define pb emplace_back
  18.  
  19. using namespace std;
  20. const int N = 400025, inf = 1e9;
  21.  
  22. vector<tuple<int,int,int>> edges;
  23. int now;
  24. struct PersistentArray {
  25.     vector<pair<int,int>> val[N];
  26.     void init(int n, function<int(int)> gen) {
  27.         for(int i = 0; i < n; i++) val[i].clear();
  28.         for(int i = 0; i < n; i++) add(i, gen(i), -1);
  29.     }
  30.     void add(int p, int d, int t=now) {
  31.         if(val[p].size() && val[p].back().first == t) val[p].back().second = d;
  32.         else val[p].pb(t, d);
  33.     }
  34.     int query(int p, int t=now) {
  35.         if(val[p].back().first <= t) return val[p].back().second;
  36.         return prev(upper_bound(val[p].begin(), val[p].end(), pair<int,int>(t, inf)))->second;
  37.     }
  38. } pa, mx;
  39. int sz[N], deg[N];
  40. int n;
  41. int anc(int x, int t=now, int r=0) {
  42.     int p = pa.query(x, t);
  43.     if(x==p) return x;
  44.     p=anc(p, t, r);
  45.     if(!r) pa.add(x, p, t);
  46.     return p;
  47. }
  48. void join(int x, int y) {
  49.     int dx = ++deg[x], dy = ++deg[y];
  50.     x = anc(x), y = anc(y);
  51.     if(x == y) {
  52.         if(mx.query(x) < 3) mx.add(x, 3);
  53.     } else {
  54.         if(sz[x] < sz[y]) swap(x, y);
  55.         sz[x] += sz[y];
  56.         int m = max({ mx.query(y), dx, dy });
  57.         if(mx.query(x) < m) mx.add(x, m);
  58.         pa.add(y, x);
  59.     }
  60. }
  61. bool ok(int t, int x, int y) {
  62.     int ax = anc(x, t, 1);
  63.     int ay = anc(y, t, 1);
  64.     return ax == ay && mx.query(ax, t) >= 3;
  65. }
  66. void init(int _n, int m, vector<int> u, vector<int> v, vector<int> w) {
  67.     n = _n;
  68.     edges.resize(m);
  69.     for(int i = 0; i < m; i++) edges[i] = {w[i], u[i], v[i]};
  70.     sort(edges.begin(), edges.end());
  71.     pa.init(n, [](int x){return x;});
  72.     mx.init(n, [](int x){return 0;});
  73.     safe;
  74.     for(int i = 0; i < n; i++) sz[i] = 1, deg[i] = 0;
  75.     now = 0;
  76.     for(int i = 0; i < m; i++) {
  77.         int a = get<1>(edges[i]), b = get<2>(edges[i]);
  78.         join(a, b);
  79.         now++;
  80.     }
  81.     /*
  82.     for(int i = 0; i < m; i++) {
  83.         for(int j = 0; j < n; j++) {
  84.             cerr << pa.query(j, i) << ' ';
  85.         }
  86.         cerr<<endl;
  87.         for(int j = 0; j < n; j++) {
  88.             cerr << mx.query(j, i) << ' ';
  89.         }
  90.         cerr<<endl;
  91.     }
  92.     */
  93. }
  94.  
  95. int getMinimumFuelCapacity(int X, int Y) {
  96.     if(!ok(edges.size(), X, Y)) return -1;
  97.     int p = -1;
  98.     for(int s = 1<<__lg(edges.size()); s; s>>=1) if(p+s < edges.size() && !ok(p+s, X, Y)) p += s;
  99.     debug(p);
  100.     return get<0>(edges[++p]);
  101.     /*
  102.     int res = -1;
  103.     for(int i = 0; i < edges.size(); i++) {
  104.         dsu.join(get<1>(edges[i]), get<2>(edges[i]), true);
  105.         if(dsu.ok(X, Y)) {
  106.             res = get<0>(edges[i]);
  107.             break;
  108.         }
  109.     }
  110.     dsu.undo();
  111.     return res;
  112.     */
  113. }
Advertisement
Add Comment
Please, Sign In to add comment