李超树

mac2022-06-30  25

模板题:BZOJ : 1568: [JSOI2008]Blue Mary开公司 给定若干条直线,求在x=x0处(x0为正整数)y的最大值。

#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<vector> #include<cmath> #define ll long long #define llu unsigned ll using namespace std; const int inf=0x3f3f3f3f; const ll lnf=0x3f3f3f3f3f3f3f3f; const int maxn=50050; const int n=50000; struct node { double k,b; int l,r,flag; }t[maxn<<2]; double cross(double k1,double b1,double k2,double b2) { return (b2-b1)/(k1-k2); } void build(int l,int r,int cnt) { t[cnt].l=l,t[cnt].r=r; t[cnt].k=t[cnt].b=0; t[cnt].flag=0; if(l==r) return ; int mid=(l+r)>>1; build(l,mid,cnt<<1); build(mid+1,r,cnt<<1|1); } void change(double k,double b,int cnt) { if(!t[cnt].flag) { t[cnt].k=k,t[cnt].b=b; t[cnt].flag=1; return ; } //如果能l==r的话,在这一点y值一定可比较,而不会向下更新。 double y1=k*t[cnt].l+b,y2=k*t[cnt].r+b; double y3=t[cnt].k*t[cnt].l+t[cnt].b,y4=t[cnt].k*t[cnt].r+t[cnt].b; if(y1<=y3&&y2<=y4) return ; if(y1>=y3&&y2>=y4) { t[cnt].k=k,t[cnt].b=b; return ; } double posx=cross(k,b,t[cnt].k,t[cnt].b); if(posx<=t[cnt<<1].r) { if(y1>=y3) change(k,b,cnt<<1); else { change(t[cnt].k,t[cnt].b,cnt<<1); t[cnt].k=k,t[cnt].b=b; } } else { if(y1>=y3) { change(t[cnt].k,t[cnt].b,cnt<<1|1); t[cnt].k=k,t[cnt].b=b; } else change(k,b,cnt<<1|1); } } double ans; void ask(int pos,int cnt) { if(t[cnt].flag) ans=max(ans,t[cnt].k*pos+t[cnt].b); if(t[cnt].l==t[cnt].r) return ; if(pos<=t[cnt<<1].r) ask(pos,cnt<<1); else ask(pos,cnt<<1|1); } int main(void) { char op[20]; int p,x; double k,b; build(1,n,1); scanf("%d",&p); for(int i=1;i<=p;i++) { scanf("%s",op); if(op[0]=='P') { scanf("%lf%lf",&b,&k); change(k,b-k,1); } else { scanf("%d",&x); ans=0; ask(x,1); printf("%lld\n",(ll)(ans/100)); } } return 0; }
最新回复(0)