李超线段树。
GTMD调了一下午。。。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 100500 #define eps 1e-8 #define inf 10000000 using namespace std; long long n,x,tot=0,root,ls[maxn<<2],rs[maxn<<2]; double s,p,b[maxn<<2],k[maxn<<2],ans=0; char type[15]; bool flag[maxn<<2]; void build(long long &now,long long left,long long right) { now=++tot;b[now]=k[now]=-inf; if (left==right) return; long long mid=(left+right)>>1; build(ls[now],left,mid); build(rs[now],mid+1,right); } double f (double s,int pos,double p) { return s+(double)(pos-1)*p; } void modify(long long now,long long left,long long right,double s,double p) { double f1,f2,f3,f4; if (!flag[now]) { k[now]=p;b[now]=s;flag[now]=true; return; } f1=s+(left-1)*p;f2=b[now]+(double)(left-1)*k[now];f3=s+(double)(right-1)*p;f4=b[now]+(double)(right-1)*k[now]; if ((f1<f2) && (f3<f4)) return; if ((f1>f2) && (f3>f4)) {b[now]=s;k[now]=p;return;} if (left==right) return;int mid=(left+right)>>1; double r1=f(s,mid,p),r2=f(b[now],mid,k[now]); if (r1>r2) {swap(s,b[now]);swap(p,k[now]);} if (!((r1<r2)^(f1>f2))) modify(ls[now],left,mid,s,p); else modify(rs[now],mid+1,right,s,p); } void ask(long long now,long long left,long long right,long long pos) { ans=max(ans,b[now]+(pos-1)*k[now]); if (left==right) return; long long mid=(left+right)>>1; if (pos<=mid) ask(ls[now],left,mid,pos); else ask(rs[now],mid+1,right,pos); } int main() { scanf("%lld",&n); build(root,1,50000); for (long long i=1;i<=n;i++) { scanf("%s",type); if (type[0]=='P') { scanf("%lf%lf",&s,&p); modify(root,1,50000,s,p); } else { scanf("%lld",&x);ans=0; ask(root,1,50000,x); printf("%lld\n",(long long)(ans/100+eps)); } } return 0; }