求数组的长度有限制的连续子段的最大平均值
加入限制:数组连续子段的长度>=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 }
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 }

浙公网安备 33010602011771号