求数组的长度有限制的连续子段的最大平均值

加入限制:数组连续子段的长度>=x

数据范围 1<=n<=1e5

枚举子段两端点显然会tle

 

方法:二分答案+前缀和

对答案进行二分(solve()函数),每次对答案进行check()(令check(ans)==1表示数组存在平均值>=ans的连续子段,否则不存在)

直到不满足二分的端点r-l>e

void solve()

 1 void solve(){
 2     double l=0,r=1e5;  //枚举ans 
 3     while(r-l>e){
 4         double mid=(l+r)/2;
 5         if(check_a(mid)){
 6             l=mid; 
 7         }
 8         else r=mid;
 9     }
10     maxa=l;
11 }
View Code

bool check(double ans)

 1 bool check(double mid){ //if mid >= S return 1 
 2     suma[0]=0;
 3     for(int i=1;i<=n;i++){
 4         ta[i]=a[i]-mid;
 5         suma[i]=suma[i-1]+ta[i];
 6     }
 7 //用到一个小技巧,如果给每个ai减去ans,只需判断后一段减前一段的前缀
 8 //和是否>=0即可
 9     double tem=0;  //?
10     for(int i=x;i<=n;i++){  //len>=x
11         tem=min(tem,suma[i-x]);
12         if(suma[i]-tem>=0) return 1;
13     }
14     return 0;
15 }
View Code

 

posted @ 2021-07-27 13:00  starlightlmy  阅读(186)  评论(0)    收藏  举报