【CodeForces】578 C. Weakness and Poorness

编程入门 行业动态 更新时间:2024-10-11 21:28:00

【<a href=https://www.elefans.com/category/jswz/34/1770097.html style=CodeForces】578 C. Weakness and Poorness"/>

【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为绝对值的一些直线,然后求上下凸包。

 

转载于:.html

更多推荐

【CodeForces】578 C. Weakness and Poorness

本文发布于:2024-02-13 10:37:30,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1758207.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:CodeForces   Poorness   Weakness

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!