P1404 平均数

首先二分答案求出一个可能的最大平均值,并用前缀和数组判断是否有连续至少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 }
原文地址:https://www.cnblogs.com/hahaha2124652975/p/11674794.html