BZOJ 1568 Blue Mary开公司

Posted on 2016-12-07 16:55  ziliuziliu  阅读(93)  评论(0编辑  收藏  举报

李超线段树。

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;
}