首先二分答案求出一个可能的最大平均值,并用前缀和数组判断是否有连续至少m个数的平均数超过该可能平均值,之后按二分常规操作就行了
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #include<queue> 7 #include<stack> 8 #include<deque> 9 #define ll long long 10 using namespace std; 11 const int oo=0x3f3f3f3f; 12 const int N=100005; 13 14 int n,m; 15 ll r,l,mid,M; 16 ll a[N],f[N]; 17 18 ll Max(ll a,ll b){return a>b?a:b;} 19 ll Min(ll a,ll b){return a<b?a:b;} 20 ll Abs(ll a){return a>0?a:-a;} 21 22 ll get(){ 23 ll zy=getchar(); 24 ll z=1,y=0; 25 while(zy>'9'||zy<'0'){ 26 if(zy=='-') z=-1; 27 zy=getchar(); 28 } 29 while(zy>='0'&&zy<='9'){ 30 y=(y<<1)+(y<<3)+zy-'0'; 31 zy=getchar(); 32 } 33 return z*y; 34 } 35 36 bool likezy(){ 37 bool ok=false; 38 ll p=M; 39 for(int i=1;i<=n;i++){ 40 f[i]=f[i-1]+a[i]-mid; 41 if(i>=m){ 42 p=Min(p,f[i-m]); 43 if(f[i]>=p) return true; 44 } 45 } 46 return false; 47 } 48 49 int main(){ 50 //freopen("P1404平均数.in","r",stdin); 51 //freopen("P1404平均数.out","w",stdout); 52 scanf("%d%d",&n,&m); 53 for(int i=1;i<=n;i++){ 54 a[i]=get()*10000; 55 r=Max(a[i],r); 56 M=r; 57 } 58 while(l<r){ 59 mid=(l+r)>>1; 60 if(likezy()) l=mid+1; 61 else r=mid-1; 62 } 63 printf("%lld ",l/10); 64 return 0; 65 }