NOI2007為替

凸包とスプレイメンテナンスは
後でCDQにそれを使用することをお勧めします。
デバッグがより困難スプレイ

/*
@Date    : 2019-08-18 08:04:31
@Author  : Adscn ([email protected])
@Link    : https://www.cnblogs.com/LLCSBlog
*/
#include<bits/stdc++.h>
using namespace std;
#define IL inline
#define RG register
#define gi getint()
#define gc getchar()
#define File(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
IL int getint()
{
    RG int xi=0;
    RG char ch=gc;
    bool f=0;
    while(ch<'0'||ch>'9')ch=='-'?f=1:f,ch=gc;
    while(ch>='0'&&ch<='9')xi=(xi<<1)+(xi<<3)+ch-48,ch=gc;
    return f?-xi:xi;
}
template<typename T>
IL void pi(T k,char ch=0)
{
    if(k<0)k=-k,putchar('-');
    if(k>=10)pi(k/10,0);
    putchar(k%10+'0');
    if(ch)putchar(ch);
}
const int N=1e5+7;
const double eps=1e-8;
double dp[N],A[N],B[N],R[N];
__inline__ __attribute__((always_inline))
int dcmp(double x){
    if(fabs(x)<eps)return 0;
    return x<0?-1:1;
}
namespace SplayTree{
    struct node;
    typedef node * tree;
    struct node{
        tree ch[2],par;
        double lk,rk;//lk>rk
        double x,y;
        node(){}
        node(const node &b,tree p){x=b.x,y=b.y,par=p,ch[0]=ch[1]=NULL;}
        inline bool operator == (const node &b)const{return dcmp(x-b.x)==0&&dcmp(y-b.y)==0;}
    }*root=NULL;
    inline bool ws(tree x,tree p){return p?p->ch[1]==x:0;}
    inline void connect(tree x,tree p,bool wh){x?(x->par=p):0,(p?p->ch[wh]:root)=x;}
    inline void rotate(tree x)
    {
        tree p=x->par,g=p->par;
        bool t=ws(x,p);
        connect(x,g,ws(p,g)),connect(x->ch[!t],p,t),connect(p,x,!t);
    }
    inline void Splay(tree x,tree y)
    {
        while(x&&x->par!=y)
        {
            tree p=x->par,g=p->par;
            if(g!=y)rotate(ws(x,p)^ws(p,g)?x:p);
            rotate(x);
        }
    }
    bool ok(tree x,double p){return x->lk+eps>=p&&x->rk<=p+eps;}
    tree find(double num)
    {
        tree x=root;
        while(x&&!ok(x,num))x=x->ch[x->lk>=num+eps];
        return Splay(x,NULL),x;
    }
    double slope(tree x,tree y){
        if(dcmp(x->x-y->x)==0)return -1e9;
        return (y->y-x->y)/(y->x-x->x);
    }
    tree pre(tree x)
    {
        tree y=x->ch[0],ret=y;
        while(y)
            if(y->lk+eps>=slope(x,y))ret=y,y=y->ch[1];
            else y=y->ch[0];
        return ret;
    }
    tree nxt(tree x)
    {
        tree y=x->ch[1],ret=y;
        while(y)
            if(y->rk<=slope(x,y)+eps)ret=y,y=y->ch[0];
            else y=y->ch[1];
        return ret;
    }
    inline void insert(node p)
    {
        if(!root)root=new node(p,NULL);
        else 
            for(tree x=root;x;x=x->ch[p.x>x->x+eps])
                if(!x->ch[p.x>x->x+eps]){
                    x->ch[p.x>x->x+eps]=new node(p,x);
                    Splay(x->ch[p.x>x->x+eps],NULL);
                    return ;
                }
    }
    inline void free_(tree &x)
    {
        if(!x)return;
        free_(x->ch[0]),free_(x->ch[1]);
        delete x;
        x=NULL;
    }
    inline void update(node now){
        insert(now);
        tree x=root;
        assert(*root==now);
        if(x->ch[0]){
            tree p=pre(x);
            Splay(p,x);free_(p->ch[1]);
            x->lk=p->rk=slope(p,x);
        }
        else x->lk=1e9;
        if(x->ch[1]){
            tree p=nxt(x);
            Splay(p,x);free_(p->ch[0]);
            x->rk=p->lk=slope(p,x);
        }
        else x->rk=-1e9;
        if(x->lk<=x->rk+eps){
            root=x->ch[0];
            connect(x->ch[1],root,1),root->par=NULL;
            root->lk=slope(root,root->ch[1]);
            if(root->ch[1])root->ch[1]->rk=root->lk;
            delete x;
        }
    }
}
using namespace SplayTree;
int main(void)
{
    int n=gi;cin>>dp[0];
    for(int i=1;i<=n;++i)
    {
        scanf("%lf%lf%lf",A+i,B+i,R+i);
        tree j=find(-A[i]/B[i]);
        dp[i]=dp[i-1];
        if(j)dp[i]=max(dp[i-1],j->x*A[i]+j->y*B[i]);
        node nw;
        nw.y=dp[i]/(A[i]*R[i]+B[i]),nw.x=nw.y*R[i];
        update(nw);
    }
    printf("%.3lf\n",dp[n]);
    return 0;
}

おすすめ

転載: www.cnblogs.com/LLCSBlog/p/11372073.html