记录编号 267050 评测结果 AAAAAAAAAA
题目名称 16.[NOI 2007]货币兑换 最终得分 100
用户昵称 TenderRun 是否通过 通过
代码语言 C++ 运行时间 0.510 s
提交时间 2016-06-10 16:43:00 内存使用 9.01 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define maxn 120000
#define eps 1e-9
#define inf 1e9
using namespace std;
int fa[maxn],ch[maxn][2];
double f[maxn],x[maxn],y[maxn],lk[maxn],rk[maxn],a[maxn],b[maxn],rate[maxn];
int n,m,rot,num;

double fabs(double x){
    return (x>0)?x:-x;
}

inline void zigzag(int x,int &rot){
    int y=fa[x],z=fa[y];
    int p=(ch[y][1]==x),q=p^1;
    if (y==rot) rot=x;
        else if (ch[z][0]==y) ch[z][0]=x; else ch[z][1]=x;
    fa[x]=z; fa[y]=x; fa[ch[x][q]]=y;
    ch[y][p]=ch[x][q]; ch[x][q]=y; 
}

inline void splay(int x,int &rot){
    while (x!=rot){
        int y=fa[x],z=fa[y];
        if (y!=rot)
            if ((ch[y][0]==x)xor(ch[z][0]==y)) zigzag(x,rot); else zigzag(y,rot);
        zigzag(x,rot);
    }
}

inline void insert(int &t,int anc,int now){
    if (t==0){
        t=now;
        fa[t]=anc;
        return ;
    }
    if (x[now]<=x[t]+eps) insert(ch[t][0],t,now);
    else insert(ch[t][1],t,now);
}

inline double getk(int i,int j){
    if (fabs(x[i]-x[j])<eps) return -inf;
    else return (y[j]-y[i])/(x[j]-x[i]);
}

inline int prev(int rot){
    int t=ch[rot][0],tmp=t;
    while (t){
        if (getk(t,rot)<=lk[t]+eps) tmp=t,t=ch[t][1];
        else t=ch[t][0];
    }
    return tmp;
}
inline int succ(int rot){
    int t=ch[rot][1],tmp=t;
    while(t){
        if(getk(rot,t)+eps>=rk[t]) tmp=t,t=ch[t][0];
        else t=ch[t][1];
    }
    return tmp;
}

inline void update(int t){
    splay(t,rot);
    if (ch[t][0]){
        int left=prev(rot);
        splay(left,ch[rot][0]); ch[left][1]=0;
        lk[t]=rk[left]=getk(left,t);
    }
    else lk[t]=inf;
    if (ch[t][1]){
        int right=succ(rot);
        splay(right,ch[rot][1]); ch[right][0]=0;
        rk[t]=lk[right]=getk(t,right);
    }
    else rk[t]=-inf;
    if (lk[t]<=rk[t]+eps){
        rot=ch[t][0]; ch[rot][1]=ch[t][1]; fa[ch[t][1]]=rot; fa[rot]=0;
        lk[rot]=rk[ch[t][1]]=getk(rot,ch[t][1]);
    }
}        

inline int find(int t,double k){
    if (t==0) return 0;
    if (lk[t]+eps>=k&&k+eps>=rk[t]) return t;
    if (k+eps>lk[t]) return find(ch[t][0],k);
    else return find(ch[t][1],k);
}

int main(){
    freopen("cash.in","r",stdin);
    freopen("cash.out","w",stdout);
    scanf("%d%lf",&n,&f[0]);
    for(int i=1;i<=n;i++)scanf("%lf%lf%lf",&a[i],&b[i],&rate[i]);
    for(int i=1;i<=n;i++){
        int j=find(rot,-a[i]/b[i]);
        f[i]=max(f[i-1],x[j]*a[i]+y[j]*b[i]);
        y[i]=f[i]/(a[i]*rate[i]+b[i]);
        x[i]=y[i]*rate[i];
        insert(rot,0,i);
        update(i);
    }
    printf("%.3lf\n",f[n]);
    return 0;
}