src/data-structures/line-container.hpp
Verified with
Code
#pragma once
/**
* Author: Teetat T.
* Description: Line Container (Minimize).
* Time: O(\log N)
*/
struct Line{
static bool querymode;
ll m,c;
mutable ll p;
Line(ll m,ll c):m(m),c(c),p(0){}
Line(ll p):m(0),c(0),p(p){}
bool operator<(const Line &o)const{
return querymode?p<o.p:m>o.m;
}
};
bool Line::querymode=false;
struct LineContainer:multiset<Line>{
ll div(ll a,ll b){
return a/b-((a^b)<0&&a%b);
}
bool isect(iterator x,iterator y){
if(y==end())return x->p=LINF,false;
if(x->m==y->m)x->p=x->c<=y->c?LINF:-LINF;
else x->p=div(x->c-y->c,y->m-x->m);
return x->p>=y->p;
}
void add(ll m,ll c){
auto x=insert(Line(m,c)),y=next(x);
while(isect(x,y))y=erase(y);
if((y=x)!=begin()&&isect(--x,y))isect(x,erase(y));
while((y=x)!=begin()&&(--x)->p>=y->p)isect(x,erase(y));
}
ll get(ll x){
if(empty())return LINF;
Line::querymode=true;
auto l=lower_bound(Line(x));
Line::querymode=false;
return l->m*x+l->c;
}
};
#line 2 "src/data-structures/line-container.hpp"
/**
* Author: Teetat T.
* Description: Line Container (Minimize).
* Time: O(\log N)
*/
struct Line{
static bool querymode;
ll m,c;
mutable ll p;
Line(ll m,ll c):m(m),c(c),p(0){}
Line(ll p):m(0),c(0),p(p){}
bool operator<(const Line &o)const{
return querymode?p<o.p:m>o.m;
}
};
bool Line::querymode=false;
struct LineContainer:multiset<Line>{
ll div(ll a,ll b){
return a/b-((a^b)<0&&a%b);
}
bool isect(iterator x,iterator y){
if(y==end())return x->p=LINF,false;
if(x->m==y->m)x->p=x->c<=y->c?LINF:-LINF;
else x->p=div(x->c-y->c,y->m-x->m);
return x->p>=y->p;
}
void add(ll m,ll c){
auto x=insert(Line(m,c)),y=next(x);
while(isect(x,y))y=erase(y);
if((y=x)!=begin()&&isect(--x,y))isect(x,erase(y));
while((y=x)!=begin()&&(--x)->p>=y->p)isect(x,erase(y));
}
ll get(ll x){
if(empty())return LINF;
Line::querymode=true;
auto l=lower_bound(Line(x));
Line::querymode=false;
return l->m*x+l->c;
}
};
Back to top page