小A与最大子段和 斜率优化 + 二分 + 细节

Posted guangheli

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小A与最大子段和 斜率优化 + 二分 + 细节相关的知识,希望对你有一定的参考价值。

Code: 

#include <bits/stdc++.h>
#define setIO(s) freopen(s".in","r",stdin) 
#define x(i) (1.0000*i) 
#define y(i) (1.0000*s2[i]*i-1.00000*s1[i])        
#define maxn 300000
#define ll long long  
#define ldb double
using namespace std;
int tail,head,n; 
int q[maxn]; 
ll s1[maxn],s2[maxn],f[maxn];     
ldb slope(int i,int j)  return (ldb)(1.0*y(i)-y(j))/(ldb)(1.0*x(i)-x(j));       
int main()
 
	int i,j;  
	ll ans=-1e18; 
	// setIO("input");  
	scanf("%d",&n);
	for(i=1;i<=n;++i) 
	
		scanf("%lld",&s2[i]); 
		s1[i]=s1[i-1]+s2[i]*i; 
		s2[i]+=s2[i-1];        
	
	head=tail=1; 
	for(i=1;i<=n;++i) 
	
		int l=head,r=tail,re=0,mid=0; 
		while(l<=r) 
		
			mid=(l+r)>>1;  
			if(mid==tail)  re=tail;  break;    
			if(slope(q[mid],q[mid+1])<=s2[i]) re=mid,r=mid-1; 
			else l=mid+1;  
		
		f[i]=s1[i]-s1[q[re]]-(s2[i]-s2[q[re]])*q[re]; 
		ans=max(ans,f[i]);   
		while(head<tail&&slope(i,q[head-1])>slope(q[head],q[head-1])) --tail;    
		q[++tail]=i; 
	  
	printf("%lld\n",ans);   
	return 0; 
 

  

以上是关于小A与最大子段和 斜率优化 + 二分 + 细节的主要内容,如果未能解决你的问题,请参考以下文章

「Newcoder练习赛40D」小A与最大子段和

SPOJ GSS3 单点修改+区间最大子段和

最大连续子段和的两种线性算法

最大连续子段和的两种线性算法

最大子段和之环形问题

最大子段和||最大子矩阵和||最大全0子矩阵||最大全0子正方形