[JSOI2008]Blue Mary开公司(李超树)

题意:传送门

题解:李超树板题,参考传送门

附上代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 50100;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
 
struct node{
    double b,k;
    bool did;
    node(double _b=0,double _k=0,bool _did=false):b(_b),k(_k),did(_did){}
};
node seg[maxn<<2];
 
double Intersection(double k1,double b1,double k2,double b2)
{
    return 1.0*(b2-b1)/(k1-k2);
}
 
void update(double k,double b,int l,int r,int rt){
    if(!seg[rt].did) seg[rt].b=b,seg[rt].k=k,seg[rt].did=true;
    else{
        double f1=k*l+b,f2=seg[rt].k*l+seg[rt].b,f3=k*r+b,f4=seg[rt].k*r+seg[rt].b;
        if(f1<=f2&&f3<=f4){
            return ;
        }else if(f1>=f2&&f3>=f4){
            seg[rt].k=k,seg[rt].b=b;
        }else{
            int m=l+r>>1;
            double len=Intersection(k,b,seg[rt].k,seg[rt].b);
            if(f1>=f2){
                if(len<=m){
                   update(k,b,lson);
                }else{
                    update(seg[rt].k,seg[rt].b,rson);
                    seg[rt].k=k; seg[rt].b=b;
                }
            }
            else{
                if(len>m){
                    update(k,b,rson);
                }else{
                    update(seg[rt].k,seg[rt].b,lson);
                    seg[rt].k=k; seg[rt].b=b;
                }
            }
        }
    }
 
}
 
 
double query(int x,int l,int r,int rt){
    double ans=0;
    if(seg[rt].did){
        ans=max(ans,1.0*x*seg[rt].k+seg[rt].b);
    }
    if(l==r){
        return ans;
    }
    int m=l+r>>1;
    if(m>=x){
        ans=max(ans,query(x,lson));
    }else{
        ans=max(ans,query(x,rson));
    }
    return ans;
}
 
int main(){
    int m;
    scanf("%d",&m);
    while(m--){
        char t[50];
        scanf("%s",t);
        if(t[0]=='P'){
            double k,b;
            scanf("%lf%lf",&b,&k);
            update(k,b-k,1,50000,1);
        }
        else{
            int x;
            scanf("%d",&x);
            printf("%d\n",(int)floor(query(x,1,50000,1)/100.0));
        }
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值