Problem Description
You are given a sequence of n integers a1, a2, ..., an.
Determine a real number x such that the weakness of the sequence a1 - x, a2 - x, ..., an - x is as small as possible.
The weakness of a sequence is defined as the maximum value of the poorness over all segments (contiguous subsequences) of a sequence.
The poorness of a segment is defined as the absolute value of sum of the elements of segment.
Input
The first line contains one integer n (1 ≤ n ≤ 200 000), the length of a sequence.
The second line contains n integers a1, a2, ..., an (|ai| ≤ 10 000).
Output
Output a real number denoting the minimum possible weakness of a1 - x, a2 - x, ..., an - x. Your answer will be considered correct if its relative or absolute error doesn't exceed 10 - 6.
Examples
Input3Output
1 2 3
1.000000000000000Input
4Output
1 2 3 4
2.000000000000000Input
10Output
1 10 2 9 3 8 4 7 5 6
4.500000000000000
Note
For the first case, the optimal value of x is 2 so the sequence becomes - 1, 0, 1 and the max poorness occurs at the segment "-1" or segment "1". The poorness value (answer) equals to 1 in this case.
For the second sample the optimal value of x is 2.5 so the sequence becomes - 1.5, - 0.5, 0.5, 1.5 and the max poorness occurs on segment "-1.5 -0.5" or "0.5 1.5". The poorness value (answer) equals to 2 in this case.
这题的思路是三分。
由于减去的x过大或过小,weakness都会过大。当x为极小值点时才会最小。即下凸函数。
三分查找最小值即可。
weakness就是数列的最大的连续子串的和的绝对值。因此分最大绝对值的原数是正数和负数讨论下即可。
精度为2e-12,3e-12。(低了会wa,高了会tle)不是很懂(应该是答案误差需要小于1e-6。n个精度相加对weakness的影响为1e-7)
#include<cstdio> #include<algorithm> using namespace std; int n; double a[200005],b[200005],r=-10005,l=10005,midl,midr,sum,ans; double weakn(double m){ ans=0; sum=0; for(int i=0;i<n;i++){ sum+=a[i]-m; if(sum<0) sum=0; ans=max(ans,sum); } sum=0; for(int i=0;i<n;i++){ sum+=m-a[i]; if(sum<0) sum=0; ans=max(ans,sum); } return ans; } int main(){ scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%lf",&a[i]); if(a[i]>r) r=a[i]; if(a[i]<l) l=a[i]; } while(r-l>2e-12){ midl=(l+r)/2; midr=(midl+r)/2; if(weakn(midl)<weakn(midr)) r=midr; else l=midl; } printf("%lf",weakn(l)); }