• 【CodeForces】578 C. Weakness and Poorness


    【题目】C. Weakness and Poorness

    【题意】给定含n个整数的序列ai,定义新序列为ai-x,要使新序列的最大子段和绝对值最小,求实数x。n<=2*10^5。

    【算法】二分||三分||计算几何(凸包)

    【题解】Editorial

    令正数最大子段和为A,负数最大子段和为B,绝对值是max(A,B)。当x从小到大变化时,A由大变小,B由小变大。

    容易发现这是一个下凸函数,可以用三分法求解。

    但是,这道题卡精度(-11会WA,-12会T),解决方法是根据复杂度把循环次数卡到极限而不用r-l<=eps的方法,以及缩小一开始的l和r范围防卡。

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<set>
    #include<vector>
    #include<algorithm>
    #define ll long long
    #define lowbit(x) x&-x
    using namespace std;
    int read(){
        char c;int s=0,t=1;
        while(!isdigit(c=getchar()))if(c=='-')t=-1;
        do{s=s*10+c-'0';}while(isdigit(c=getchar()));
        return s*t;
    }
    int ab(int x){return x>0?x:-x;}
    //int MO(int x){return x>=MOD?x-MOD:x;}
    //void insert(int u,int v){tot++;e[tot].v=v;e[tot].from=first[u];first[u]=tot;}
    /*------------------------------------------------------------*/
    const int maxn=200010;
    const double eps=1e-9;
    
    int n;
    double a[maxn],b[maxn];
    
    double F(double x){
        for(int i=1;i<=n;i++)b[i]=a[i]-x;
        double sum=0,ans=0;
        for(int i=1;i<=n;i++){
            sum+=b[i];
            if(sum<0)sum=0;
            ans=max(ans,sum);
        }
        sum=0;
        for(int i=1;i<=n;i++){
            sum+=b[i];
            if(sum>0)sum=0;
            ans=max(ans,-sum);
        }
        return ans;
    }
    int main(){
        n=read();
        double m1,m2,l=-10010,r=10010;
        for(int i=1;i<=n;i++)scanf("%lf",&a[i]);
        for(int i=1;i<=100;i++){
            m1=l+(r-l)/3;m2=l+(r-l)/3*2;
            if(F(m1)<F(m2))r=m2;else l=m1;
        }
        printf("%.10lf",F(l));
        return 0;
    }
    View Code

    进一步观察,发现答案出现在A=B时,当x偏小时A>B,当x偏大时A<B,那么可以二分求解。

    最后的几何解法,将max(si-sj)展开后化为以x为自变量,y为绝对值的一些直线,然后求上下凸包。

     
  • 相关阅读:
    nginx中目录转义字符问题
    2022年3月2日最近的状态~
    [esp8266]官方SDK与arduino ROM或Flash布局,Vscode+platformio 如何设置
    什么是并发容器
    Executor, ExecutorService 和 Executors区别与联系
    Spirng和SpringBoot中的Aop优先使用的是JDK动态代理还是Cglib
    建造者模式
    MySQL四大排名函数
    SpringMVC执行流程解析(PS:使用了适配器模式)
    适配器模式
  • 原文地址:https://www.cnblogs.com/onioncyc/p/8005275.html
Copyright © 2020-2023  润新知