Advertisement
Guest User

Untitled

a guest
May 20th, 2018
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.22 KB | None | 0 0
  1. class ConvexHullDynamic{
  2.     typedef long long coef_t;
  3.     typedef long long coord_t;
  4.     typedef long long val_t;
  5.     struct Line{
  6.         coef_t a, b;
  7.         double left_x;
  8.         coord_t val;
  9.         bool type;
  10.         Line(coef_t a=0, coef_t b=0) : a(a), b(b), left_x(-INFINITY), val(0), type(false) {}
  11.         val_t eval(coord_t x) const{
  12.             return a * x + b;
  13.         }
  14.         friend bool paralel(const Line & a, const Line & b){
  15.             return a.a == b.a;
  16.         }
  17.         friend double inter(const Line & a, const Line & b){
  18.             if(paralel(a, b)) return INFINITY;
  19.             return -1.0 * (a.b - b.b) / (a.a - b.a);
  20.         }
  21.         bool operator < (const Line & line) const{
  22.             if(line.type == false) return this -> a > line.a;
  23.             return this -> left_x < line.val;
  24.         }
  25.     };
  26.     set<Line> hull;
  27.     bool isMax;
  28. public:
  29.     bool hasNext(set<Line>::iterator it){
  30.         return it != hull.end() && next(it) != hull.end();
  31.     }
  32.     bool hasPrev(set<Line>::iterator it){
  33.         return it != hull.begin();
  34.     }
  35.     bool irrelevant(set<Line>::iterator it){
  36.         return hasPrev(it) && hasNext(it) &&
  37.         (inter(*prev(it), *next(it)) < inter(*prev(it), *it));
  38.     }
  39.     set<Line>::iterator updBorder(set<Line>::iterator it){
  40.         if(!hasPrev(it)) return it;
  41.         Line tmp(*it);
  42.         double lef = inter(tmp, *prev(it));
  43.         it = hull.erase(it);
  44.         tmp.left_x = lef;
  45.         it = hull.insert(it, tmp);
  46.         return it;
  47.     }
  48.     ConvexHullDynamic(bool isMax) : isMax(isMax){}
  49.     val_t find(coord_t x){
  50.         if(hull.empty()){
  51.             if(isMax){
  52.                 return -INFINITY;
  53.             }
  54.             else{
  55.                 return INFINITY;
  56.             }
  57.         }
  58.         Line q;
  59.         q.val = x;
  60.         q.type = true;
  61.         set<Line>::iterator it = hull.lower_bound(q);
  62.         --it;
  63.         if(isMax) return -it->eval(x);
  64.         else return it->eval(x);
  65.     }
  66.     void insert(coord_t a, coord_t b){
  67.         if(isMax){
  68.             a = -a;
  69.             b = -b;
  70.         }
  71.         Line l3(a, b);
  72.         set<Line>::iterator it = hull.lower_bound(l3);
  73.         if(it != hull.end() && paralel(*it, l3)){
  74.             if(it -> b <= b) return;
  75.             it = hull.erase(it);
  76.         }
  77.         it = hull.insert(it, l3);
  78.         if(irrelevant(it)){
  79.             hull.erase(it);
  80.             return;
  81.         }
  82.         while(hasNext(it) && irrelevant(next(it)))
  83.             hull.erase(next(it));
  84.         while(hasPrev(it) && irrelevant(prev(it)))
  85.         hull.erase(prev(it));
  86.         it = updBorder(it);
  87.         if(hasNext(it)) updBorder(next(it));
  88.     }
  89.  
  90. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement