Kevin_Zhang

Untitled

Nov 2nd, 2019
417
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.12 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){}
  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. template<typename T, typename cmp>
  10. struct convex_hull{
  11.     convex_hull():h(0){};
  12.     struct frac_cmp{bool operator()(const pair<T,T> &a, const pair<T,T> &b)const{return a.first * b.second <= a.second * b.first;}};
  13.     int h;
  14.     vector< line<T> > q;
  15.     int size()const{return q.size()-h;}
  16.     void push_back(line<T> l){
  17.         if(!q.empty() and q.back().a == l.a)l.b = cmp()(l.b, q.back().b) ? l.b : q.back().b, q.pop_back();
  18.         while(size() >= 2 and frac_cmp()(intersect(q[q.size()-2], l), q.back().sect))q.pop_back();
  19.         if(!q.empty())l.sect = intersect(q.back(), l);
  20.         q.emplace_back(l);
  21.         // if((q.size()>>1)<= h)q.erase(q.begin(), q.begin()+h), h = 0;
  22.     }
  23.     void push_back(T a, T b){push_back(line<T>(a, b));}
  24.     T operator()(T x){
  25.         while(size() >= 2 and !cmp()(q[h](x), q[h+1](x)))++h;
  26.         return q[h](x);
  27.     }
  28.     void clear(){h = 0, q.clear();}
  29. };
Advertisement
Add Comment
Please, Sign In to add comment