• CDQ分治模板


    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define eps 1e-9
    using namespace std;
    const int M=200010;
    int n,i,top,stack[M];
    double f[M];
    struct shit{double x,y,k,a,b,rate;int id;}p[M],q[M];
    bool cmp(shit x,shit y){return x.k>y.k;}
    double K(int x,int y){
        if (!y)return -1e20;
        if (fabs(q[x].x-q[y].x)<eps)return 1e20;
        return (q[y].y-q[x].y)/(q[y].x-q[x].x);
    }
    void cdq(int l,int r){
        int mid=l+r>>1,L=l,R=mid+1,j=1;
        if (l==r){
            f[l]=max(f[l],f[l-1]);
            q[l].y=f[l]/(q[l].rate*q[l].a+q[l].b);
            q[l].x=q[l].y*q[l].rate;
            return;                                       更新ans,利用已经计算好的l的最优决策k,计算f [l]值,Exit 
        }
        for (int i=l;i<=r;i++)
            if (q[i].id<=mid)p[L++]=q[i];
                else p[R++]=q[i];
        for (int i=l;i<=r;i++)q[i]=p[i];
        cdq(l,mid);
        top=0;
        for (int i=l;i<=mid;i++){
            while (top>1&&K(stack[top-1],stack[top])<K(stack[top-1],i)+eps)top--;
            stack[++top]=i;                                                          对[l, mid-1]这一段扫描一遍计算出决策的凸线,
        }
        stack[++top]=0;
        for (int i=mid+1;i<=r;i++){
            while (j<top&&K(stack[j],stack[j+1])+eps>q[i].k)j++;
            f[q[i].id]=max(f[q[i].id],q[stack[j]].x*q[i].a+q[stack[j]].y*q[i].b);  
                                                                                     由于[mid+1 .. r]这一段以 -a[i] / b[i]的排序在预处理已经完成,
                                                                                     因此只需要扫描一遍更新[mid + 1 .. r] 的最优决策. 
        }
        cdq(mid+1,r);
        L=l,R=mid+1;
        for (int i=l;i<=r;i++)
            if (((q[L].x<q[R].x||(fabs(q[L].x-q[R].x)<eps&&q[L].y<q[R].y))||R>r)&&L<=mid)p[i]=q[L++];
                else p[i]=q[ ++];
        for (int i=l;i<=r;i++)q[i]=p[i];                                             利用[l, mid-1]已排好序的f []值和[mid+1, r]已排好序的f []值归并排序将 [l, r]这一段按f[]值排序.
    }
    int main(){
        scanf("%d%lf",&n,&f[0]);
        for (i=1;i<=n;i++){
            scanf("%lf%lf%lf",&q[i].a,&q[i].b,&q[i].rate);
            q[i].k=-q[i].a/q[i].b;
            q[i].id=i;
        }   
        sort(q+1,q+n+1,cmp);
        cdq(1,n);
        printf("%.3lf
    ",f[n]);
    }
  • 相关阅读:
    日记1
    JDK、JRE、JVM三者间的关系
    线性表之二,SLINKLIST(单链表)类,模板类及C链表(增删改查,广义表
    线性表之一,SEQLIST(顺序表)类及其父类LIST,模板类及C结构体,包装顺序表
    PTA(中国人民解放军陆军工程大学数据结构,C语言)
    冒泡排序
    选择排序、堆排序
    冒泡排序,快速排序
    springMVC定时器
    MD5加密
  • 原文地址:https://www.cnblogs.com/myx12345/p/6439894.html
Copyright © 2020-2023  润新知