#pragma once
#include<cassert>
#include<set>usingnamespacestd;enumObjective{MAXIMIZE=+1,MINIMIZE=-1,};template<typenameT>structLine{mutableTk,m,p;booloperator<(constLine&o)const{returnk<o.k;}booloperator<(Tx)const{returnp<x;}};template<typenameT>Tlc_inf(){returnnumeric_limits<T>::max();}template<>longdoublelc_inf<longdouble>(){return1/.0;}template<typenameT>Tlc_div(Ta,Tb){returna/b-((a^b)<0anda%b);}template<>longdoublelc_div(longdoublea,longdoubleb){returna/b;};template<typenameT,Objectiveobjective>structLineContainer:multiset<Line<T>,less<>>{usingsuper=multiset<Line<T>,less<>>;usingsuper::begin,super::end,super::insert,super::erase;usingsuper::empty,super::lower_bound;constTinf=lc_inf<T>();boolinsect(typenamesuper::iteratorx,typenamesuper::iteratory){if(y==end())returnx->p=inf,false;if(x->k==y->k)x->p=(x->m>y->m?inf:-inf);elsex->p=lc_div(y->m-x->m,x->k-y->k);returnx->p>=y->p;}voidadd(Tk,Tm){autoz=insert({k*objective,m*objective,0}),y=z++,x=y;while(insect(y,z))z=erase(z);if(x!=begin()andinsect(--x,y))insect(x,y=erase(y));while((y=x)!=begin()and(--x)->p>=y->p)insect(x,erase(y));}Tquery(Tx){assert(!empty());autol=*lower_bound(x);return(l.k*x+l.m)*objective;}};template<typenameT>usingMinLineContainer=LineContainer<T,Objective::MINIMIZE>;template<typenameT>usingMaxLineContainer=LineContainer<T,Objective::MAXIMIZE>;/**
* @brief Line container
*/
#line 2 "data-structure/line-container.hpp"
#include<cassert>
#include<set>usingnamespacestd;enumObjective{MAXIMIZE=+1,MINIMIZE=-1,};template<typenameT>structLine{mutableTk,m,p;booloperator<(constLine&o)const{returnk<o.k;}booloperator<(Tx)const{returnp<x;}};template<typenameT>Tlc_inf(){returnnumeric_limits<T>::max();}template<>longdoublelc_inf<longdouble>(){return1/.0;}template<typenameT>Tlc_div(Ta,Tb){returna/b-((a^b)<0anda%b);}template<>longdoublelc_div(longdoublea,longdoubleb){returna/b;};template<typenameT,Objectiveobjective>structLineContainer:multiset<Line<T>,less<>>{usingsuper=multiset<Line<T>,less<>>;usingsuper::begin,super::end,super::insert,super::erase;usingsuper::empty,super::lower_bound;constTinf=lc_inf<T>();boolinsect(typenamesuper::iteratorx,typenamesuper::iteratory){if(y==end())returnx->p=inf,false;if(x->k==y->k)x->p=(x->m>y->m?inf:-inf);elsex->p=lc_div(y->m-x->m,x->k-y->k);returnx->p>=y->p;}voidadd(Tk,Tm){autoz=insert({k*objective,m*objective,0}),y=z++,x=y;while(insect(y,z))z=erase(z);if(x!=begin()andinsect(--x,y))insect(x,y=erase(y));while((y=x)!=begin()and(--x)->p>=y->p)insect(x,erase(y));}Tquery(Tx){assert(!empty());autol=*lower_bound(x);return(l.k*x+l.m)*objective;}};template<typenameT>usingMinLineContainer=LineContainer<T,Objective::MINIMIZE>;template<typenameT>usingMaxLineContainer=LineContainer<T,Objective::MAXIMIZE>;/**
* @brief Line container
*/