P1404 平均数
二分答案,问题在于怎么O(n)check,把每个数都-mid,然后求前缀和,有点像最大子段和,精度问题的话就都乘1000
#include <iostream> #include <cstdio> #include <queue> #include <algorithm> #include <cmath> #include <cstring> #define inf 2147483647 #define N 1000010 #define p(a) putchar(a) #define For(i,a,b) for(long long i=a;i<=b;++i) //by war //2019.8.26 using namespace std; long long n,m; long long a[N],sum[N],Min,l,r,mid; void in(long long &x){ long long y=1;char c=getchar();x=0; while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();} while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();} x*=y; } void o(long long x){ if(x<0){p('-');x=-x;} if(x>9)o(x/10); p(x%10+'0'); } bool check(long long x){ Min=0; For(i,1,m-1) sum[i]=sum[i-1]+a[i]-x; For(i,m,n){ sum[i]=sum[i-1]+a[i]-x; if(sum[i]-Min>=0) return 1; Min=min(Min,sum[i-m+1]); } return 0; } signed main(){ in(n);in(m); For(i,1,n){ in(a[i]); a[i]*=1000; } l=1;r=2000010; while(l<r){ mid=(l+r)>>1; if(check(mid)) l=mid+1; else r=mid; } o(l-1); return 0; }