#include <bits/stdc++.h>
using std::cin;
using std::cout;
using LL = long long;
using ull = unsigned long long;
using ld = long double;
const int maxn = 4e5+10; // 总线段
const int maxm=39990; // 值域
const ld eps = 1e-7;
int n;
bool eq(ld x,ld y) {
return fabsl(x-y)<eps;
}
struct Seg {
ld k,b;
int l,r;
int id;
ld operator()(int x) const {
if(l<=x && x<=r) return k*x+b;
else return -INFINITY;
// if max, it's -INF; or, it's INF.
// make sure you won't choose illegal segs
}
} t[maxm<<2];
**define**{: #define .hash} lid id<<1
**define**{: #define .hash} rid id<<1|1
// 向下标记
//void upd(int id,int l,int r,Seg f) {
// Seg &now = t[id];
// int mid=l+r>>1;
// // 根据mid上的取值进行分讨,tag存mid上最优的线段
// if(f(mid) > now(mid)) {
// // 先看自己更不更新
// if(now(l) > f(l)) upd(lid,l,mid,now);
// if(now(r) > f(r)) upd(rid,mid+1,r,now);
// // 说明原来存的线段还有利用价值(now在交点以外的部分仍然更优)
// // 接着向下改
// now = f;
// } else {
// if(f(l) > now(l)) upd(lid,l,mid,f);
// if(f(r) > now(r)) upd(rid,mid+1,r,f);
// }
//}
void upd(int id,int l,int r,Seg f) {
Seg &now = t[id];
int mid=l+r>>1;
if(f(mid) > now(mid)) std::swap(now,f); // 动态开点这么写就寄了,只能swap线段的k和b(要保证f的ls/rs=0)
if(f(l) > now(l)) upd(lid,l,mid,f);
if(f(r) > now(r)) upd(rid,mid+1,r,f);
}
// 返回线段(如有需要可以在Seg里打上id)
// 注意是标记永久化,每一层都要和自己t[id]取个max/min
Seg smax(const Seg& a,const Seg& b,int x) {
if(a(x) > b(x)) return a;
else return b;
}
Seg qry(int id,int l,int r,int pos) {
if(l==r) return t[id];
int mid=l+r>>1;
if(pos<=mid) return smax(t[id],qry(lid,l,mid,pos),pos);
else return smax(t[id],qry(rid,mid+1,r,pos),pos);
}
void join(int id,int l,int r,int ll,int rr,Seg i) {
if(l==ll && r==rr) {
upd(id,l,r,i);
return ;
}
int mid=l+r>>1;
if(rr<=mid) join(lid,l,mid,ll,rr,i);
else if(ll>mid) join(rid,mid+1,r,ll,rr,i);
else join(lid,l,mid,ll,mid,i),join(rid,mid+1,r,mid+1,rr,i);
}
// 李超树合并优化dp
// 动态开点!
**define**{: #define .hash} lid t[id].ls
**define**{: #define .hash} rid t[id].rs
int merge(int id, int y, int l, int r) {
if (!id || !y) return id + y;
upd(id, l, r, t[y]);
int mid = l+r>>1;
lid = merge(lid, t[y].ls, l, mid);
rid = merge(rid, t[y].rs, mid + 1, r);
return id;
}
/*
if(x0==x1) {
k = {0,std::max(y0,y1),x0,x0,tot};
} else {
k.k=1.0L*(y1-y0)/(x1-x0);
k.b=1.0L*y1-k.k*x1;
k.l= std::min(x0,x1);
k.r= std::max(x0,x1);
k.id=tot;
}
*/