Advertisement
Kevin_Zhang

Untitled

Nov 2nd, 2019
503
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.93 KB | None | 0 0
  1. template<typename T>
  2. struct line{
  3.     T a, b;
  4.     pair<T,T> sect;
  5.     line(T a, T b):a(a), b(b), sect({a, b}){}
  6.     T operator()(T x)const{return a*x + b;}
  7. };
  8. template<typename S> pair<S,S> intersect(const line<S> &a, const line<S> &b){if(b.a < a.a)return make_pair(b.b-a.b, a.a-b.a);else return make_pair(a.b-b.b, b.a-a.a);}
  9. bool cmp_a = true;
  10. template<typename T, typename cmp, long long inf = 1ll << 60 >
  11. struct dynamic_convex_hull{
  12.     dynamic_convex_hull(){};
  13.     struct frac_cmp{bool operator()(const pair<T,T> &a, const pair<T,T> &b)const{return a.first == -inf ? true : (__int128)a.first * b.second <= (__int128)a.second * b.first;}};
  14.     struct frac_less{bool operator()(const pair<T,T> &a, const pair<T,T> &b)const{return a.first == -inf ? true : (__int128)a.first * b.second < (__int128)a.second * b.first;}};
  15.     struct line_cmp{
  16.         bool operator()(const line<T> &a, const line<T> &b)const{
  17.             return cmp_a ? cmp()(b.a, a.a) : frac_less()(a.sect, b.sect);
  18.         }
  19.     };
  20.     set<line<T>, line_cmp> q;
  21.     int size()const{return q.size();}
  22.     void insert(line<T> l){
  23.         cmp_a = true;
  24.         auto it = q.find(l);
  25.         if(it != q.end()){
  26.             if(!cmp()(l.b, it->b))return;
  27.             q.erase(it);
  28.         }
  29.         it = q.lower_bound(l);
  30.         if(it == q.begin() || it == q.end() || !frac_cmp()(intersect(l, *it), intersect(*prev(it), l))){
  31.             while(it != q.begin() and prev(it) != q.begin() and frac_cmp()(intersect(*prev(prev(it)), l), prev(it)->sect))q.erase(prev(it));
  32.             while(it != q.end() and next(it) != q.end() and frac_cmp()(next(it)->sect, intersect(l, *it)))it = q.erase(it);
  33.             if(it == q.begin())l.sect = make_pair(-inf, 1);
  34.             else l.sect = intersect(*prev(it), l);
  35.             q.insert(l);
  36.             if(it != q.end()){
  37.                 line<T> tmp = *it;
  38.                 tmp.sect = intersect(l, tmp);
  39.                 q.erase(it);
  40.                 q.insert(tmp);
  41.             }
  42.         }
  43.     }
  44.     void insert(T a, T b){insert(line<T>(a, b));}
  45.     T operator()(T x){
  46.         cmp_a = false;
  47.         return (*prev(q.upper_bound(line<T>(x, 1))))(x);
  48.     }
  49.     void clear(){q.clear();}
  50. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement