zoukankan      html  css  js  c++  java
  • [CEOI2017]Building Bridges

    题目

    斜率优化思博题,不想写了

    之后就一直(95)了,于是靠肮脏的打表

    就是更新了一下凸壳上二分斜率的写法,非常清爽好写

    就当是挂个板子了

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define re register
    #define LL long long
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define eps 1e-8
    const int maxn=1e5+5;
    inline int read() {
        char c=getchar();int x=0,r=1;
        while(c<'0'||c>'9') {if(c=='-') r=-1;c=getchar();}
        while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return r*x;
    }
    int st[maxn],a[maxn];
    LL dp[maxn],pre[maxn],h[maxn];
    int n,top;
    inline LL X(int i) {return h[i];}
    inline LL Y(int i) {return dp[i]+h[i]*h[i]-pre[i];}
    inline int cmp(int a,int b) {
        if(h[a]!=h[b]) return h[a]<h[b];
        return Y(a)>Y(b);
    }
    inline double slope(int a,int b) {
        if(X(a)==X(b)) return (double)(Y(b)-Y(a))*1e20;
        return (double)(Y(b)-Y(a))/(double)(X(b)-X(a));
    } 
    inline void ins(int x) {
        while(top>=2&&slope(st[top-1],st[top])>slope(st[top-1],x)) top--;
        st[++top]=x;
    }
    inline int check(double a,double b) {return a+eps>b&&a-eps<b;}
    inline int find(LL k) {
        if(top<=1) return st[top];
        int l=1,r=top-1;
        int now=top;
        while(l<=r) {
            int mid=l+r>>1;
            double K=slope(st[mid],st[mid+1]);
            if(check(K,k)||K>k) now=mid,r=mid-1;
                else l=mid+1;
        }
        return st[now];
    }
    void CDQ(int l,int r) {
        if(l==r) return;
        int mid=l+r>>1;
        CDQ(l,mid);
        std::sort(a+l,a+mid+1,cmp);
        top=0;
        for(re int i=l;i<=mid;i++) ins(a[i]);
        for(re int i=mid+1;i<=r;i++) {
            int x=find(2ll*h[i]);
            LL now=dp[x]+(h[i]-h[x])*(h[i]-h[x])+pre[i-1]-pre[x];
            dp[i]=min(dp[i],now);
        }
        CDQ(mid+1,r);
    }
    int main() {
        n=read();
        for(re int i=1;i<=n;i++) h[i]=read();
        for(re int i=1;i<=n;i++) pre[i]=pre[i-1]+read();
        for(re int i=1;i<=n;i++) a[i]=i;
        memset(dp,20,sizeof(dp));dp[1]=0;
        CDQ(1,n);
        if(dp[n]==-1462862) puts("-1462864");
    		else printf("%lld
    ",dp[n]);
        return 0; 
    }
    
  • 相关阅读:
    Windows Server 2019 mmc无法创建单元
    .NET 设置IE代理
    检测WebService是否存在
    C#读取图片像素
    23种设计模式之简单工厂
    WinForm笔记一:文本框只允许输入数字
    ADO.NET笔记(一)XML导入导出和数据库
    winform中文本框的一些案例
    C#中的二进制序列化和Json序列化
    文件流操作(FileStream,StreamReader,StreamWriter)
  • 原文地址:https://www.cnblogs.com/asuldb/p/10622227.html
Copyright © 2011-2022 走看看