zoukankan      html  css  js  c++  java
  • BZOJ 1492 [NOI2007]货币兑换Cash

    题解:

    题意不能说明白了?????

    比例到底是数量还是价值??????

    平衡树维护凸包

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    using namespace std;
    const int maxn=200009;
    const int oo=1000000000;
    const double eps=1e-9;
    
    int dcmp(double x){
        if(fabs(x)<eps)return 0;
        if(x>0)return 1;
        else return -1;
    }
    
    int n;
    double A[maxn],B[maxn],R[maxn],f[maxn];
    double Getx(int i){
        return f[i]*R[i]/(R[i]*A[i]+B[i]);
    }
    double Gety(int i){
        return f[i]/(R[i]*A[i]+B[i]);
    }
    double GetK(int i,int j){
        double xi=Getx(i),yi=Gety(i);
        double xj=Getx(j),yj=Gety(j);
        return (yi-yj)/(xi-xj);
    }
    
    int nn=0,root=0;
    int fa[maxn]={0},ch[maxn][2]={0};
    double lk[maxn],rk[maxn];
    
    int son(int x){
        if(ch[fa[x]][0]==x)return 0;
        else return 1;
    }
    
    void Rotate(int x){
        int y=fa[x];
        int z=fa[y];
        int b=son(x),c=son(y);
        int a=ch[x][b^1];
        if(z)ch[z][c]=x;
        else root=x;
        fa[x]=z;
        if(a)fa[a]=y;
        ch[y][b]=a;
        fa[y]=x;ch[x][b^1]=y;
    }
    
    void Splay(int x,int i){
        while(fa[x]!=i){
            int y=fa[x];
            int z=fa[y];
            if(z==i){
                Rotate(x);
            }else{
                if(son(x)==son(y)){
                    Rotate(y);Rotate(x);
                }else{
                    Rotate(x);Rotate(x);
                }
            }
        }
    }
    
    void Del(){
        int x=root;
        if((!ch[x][0])&&(!ch[x][1])){
            root=0;
        }else if(!ch[x][0]){
            root=ch[x][1];
            fa[ch[x][1]]=0;
            lk[ch[x][1]]=oo;
        }else if(!ch[x][1]){
            root=ch[x][0];
            fa[ch[x][0]]=0;
            rk[ch[x][0]]=-oo;
        }else{
            int pre=ch[x][0];
            int suc=ch[x][1];
            while(ch[pre][1])pre=ch[pre][1];
            while(ch[suc][0])suc=ch[suc][0];
            Splay(pre,x);Splay(suc,x);
            ch[pre][1]=suc;fa[suc]=pre;
            root=pre;fa[pre]=0;
            rk[pre]=lk[suc]=GetK(pre,suc);
        }
    }
    
    void Ins(int p){
        double xp=Getx(p);
        int x=root,y=0;
    //    cout<<"inseting"<<endl;
        while(x){
            y=x;
            double xi=Getx(x);
            if(dcmp(xi-xp)==0){
                if(dcmp(Gety(x)-Gety(p))>=0){
                    return;
                }else{
                    Splay(x,0);Del();Ins(p);return;
                }
            }
            if(xp>xi)x=ch[x][1];
            else x=ch[x][0];
        }
    //    cout<<"endinseting"<<endl;
        fa[x=p]=y;
        if(!y){
            root=x;
        }else{
            if(Getx(x)>Getx(y))ch[y][1]=x;
            else ch[y][0]=x;
        }
        Splay(x,0);
        int pre=ch[x][0];
        while(ch[pre][1])pre=ch[pre][1];
        int suc=ch[x][1];
        while(ch[suc][0])suc=ch[suc][0];
        if(!pre)lk[x]=oo;
        else lk[x]=rk[pre]=GetK(x,pre);
        if(!suc)rk[x]=-oo;
        else rk[x]=lk[suc]=GetK(x,suc);
    }
    
    void QueryK(double k){
        int x=root;
        while(x){
            if(lk[x]>=k&&rk[x]<=k){
                Splay(x,0);return;
            }else if(rk[x]>=k){
                if(ch[x][1]){
                    x=ch[x][1];
                }else{
                    Splay(x,0);return;
                }
            }else{
                if(ch[x][0]){
                    x=ch[x][0];
                }else{
                    Splay(x,0);return;
                }
            }
        }
    }
    
    void Getrk(int x,int p){
        int y=0;
        while(x){
            if(dcmp(lk[x]-GetK(x,p)>=0)){
                y=x;x=ch[x][1];
            }else{
                x=ch[x][0];
            }
        }
        if(y==0)return;
        Splay(y,p);
        ch[y][1]=0;
        rk[y]=lk[p]=GetK(y,p);
    }
    void Getlk(int x,int p){
        int y=0;
        while(x){
            if(dcmp(rk[x]-GetK(x,p))<=0){
                y=x;x=ch[x][0];
            }else{
                x=ch[x][1];
            }
        }
        if(y==0)return;
        Splay(y,p);
        ch[y][0]=0;
        rk[p]=lk[y]=GetK(y,p);
    }
    
    int main(){
        scanf("%d%lf",&n,&f[0]);
        for(int i=1;i<=n;++i)scanf("%lf%lf%lf",&A[i],&B[i],&R[i]);
        
        for(int i=1;i<=n;++i){
            double k;
            if(dcmp(B[i])==0)k=-oo;
            else k=-A[i]/B[i];
            
            f[i]=f[i-1];
            QueryK(k);
            if(root)f[i]=max(f[i],(A[i]*Getx(root)+B[i]*Gety(root)));
            
            Ins(i);
            if(root!=i)continue;
            if(lk[i]<rk[i]){
                Del();
            }else{
                if(ch[i][0]){
                    Getrk(ch[i][0],i);
                }
                if(ch[i][1]){
                    Getlk(ch[i][1],i);
                }
            }
        }
        
        printf("%.3f
    ",f[n]);
        return 0;
    }
    自己还是太辣鸡了
  • 相关阅读:
    [数据知识]DAMA数据管理—引论
    How to clear/delete all the partition table from a disk or partition in Linux
    Rust Safe Coding Notes
    量化交易平台
    斯坦福大学——人工智能本科4年课程清单
    去中心化数字身份DID简介——五、DID的应用
    linux c 打印时间最简单的实例
    sqlalchemy中Column的默认值属性
    Ubuntu安装jdk8的两种方式
    面试官:手撕十大排序算法,你会几种?(转)
  • 原文地址:https://www.cnblogs.com/zzyer/p/8610172.html
Copyright © 2011-2022 走看看