https://www.luogu.com.cn/problem/P4254
李超线段树板题,注意最后要跟0比较一下大小,因为可以选择不做亏本生意
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxl=1e5+10;
int n,m=5e4,tot;
struct node
{
int l,r,id;
}tr[maxl<<2];
char s[maxl];
struct line
{
double k,b;
}a[maxl];
inline void build(int k,int l,int r)
{
tr[k].l=l;tr[k].r=r;tr[k].id=1;
if(l==r)
return;
int mid=(l+r)>>1;
build(k<<1,l,mid);build(k<<1|1,mid+1,r);
}
inline double fun(int id,int x){return a[id].k*x+a[id].b;}
inline void upd(int k,int id)
{
if(tr[k].l==tr[k].r)
{
if(fun(id,tr[k].l)>fun(tr[k].id,tr[k].l))
tr[k].id=id;
return;
}
int mid=(tr[k].l+tr[k].r)>>1;
if(a[tr[k].id].k<a[id].k)
{
if(fun(id,mid)>fun(tr[k].id,mid))
{
upd(k<<1,tr[k].id);
tr[k].id=id;
}
else upd(k<<1|1,id);
}
else
{
if(fun(id,mid)>fun(tr[k].id,mid))
{
upd(k<<1|1,tr[k].id);
tr[k].id=id;
}
else upd(k<<1,id);
}
}
inline double qry(int k,int x)
{
if(tr[k].l==tr[k].r)
return fun(tr[k].id,x);
int mid=(tr[k].l+tr[k].r)>>1;
if(x<=mid)
return max(fun(tr[k].id,x),qry(k<<1,x));
else
return max(fun(tr[k].id,x),qry(k<<1|1,x));
}
int main()
{
scanf("%d",&n);
build(1,1,m);a[0].k=a[0].b=0;
for(int i=1;i<=n;i++)
{
scanf("%s",s);
if(s[0]=='P')
{
++tot;scanf("%lf%lf",&a[tot].b,&a[tot].k);
a[tot].b-=a[tot].k;
upd(1,tot);
}
else
{
int x;scanf("%d",&x);
if(tot>0)
{
//printf("%.8f\n",qry(1,x));
printf("%lld\n",max(0ll,(ll)(qry(1,x)/100)));
}
else puts("0");
}
}
return 0;
}