SUOI07 区间平均++ (二分答案+前缀和)

Posted ressed

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SUOI07 区间平均++ (二分答案+前缀和)相关的知识,希望对你有一定的参考价值。

https://www.vijos.org/d/SUOI/p/59dc5af7d3d8a1361ae62b97

二分一个答案,然后做一做前缀和,用满足区间大小的最小值减一减,判断答案合不合法

然而还要输出一个最小的区间 太毒瘤了

但其实最后答案中最小区间的端点就只能是刚才做的那个最小值,因为如果不是最小值,那这个答案一定不是最优的

然后再随便对比一下就完事了

(感觉什么都没说清,看代码吧代码好看代码也不好看

 1 #include<bits/stdc++.h>
 2 #define pa pair<int,int>
 3 #define ll long long
 4 using namespace std;
 5 const int maxn=1e6+5;
 6 
 7 inline ll rd(){
 8     ll x=0;char c=getchar();int neg=1;
 9     while(c<0||c>9){if(c==-) neg=-1;c=getchar();}
10     while(c>=0&&c<=9) x=x*10+c-0,c=getchar();
11     return x*neg;
12 }
13 
14 int N,K,Ma,Mi,num[maxn];
15 double sum[maxn];
16 
17 inline bool judge(int &x,int &y,double r){
18     int a=-1,b=N+1;
19     for(int i=1;i<=N;i++) sum[i]=sum[i-1]+num[i]-r;
20     double mi=1e9;int mn;bool re=0;
21     for(int i=K;i<=N;i++){
22         if(mi>=sum[i-K]) mi=sum[i-K],mn=i-K;
23         if(sum[i]>=mi){
24             re=1;if(b-a>i-mn||(b-a==i-mn&&mn<a)) a=mn,b=i;
25         }
26     }if(re) x=a+1,y=b;
27     return re;
28 }
29 
30 int main(){
31     int i,j,k;
32     N=rd();K=rd();Ma=-10000;Mi=10000;
33     for(i=1;i<=N;i++) num[i]=rd(),Ma=max(num[i],Ma),Mi=min(num[i],Mi);
34     double l=Mi-1,r=Ma+1;int a,b;
35     while(l<=r-1e-7){
36         double m=(l+r)/2;
37         if(judge(a,b,m)) l=m+1e-6;
38         else r=m-1e-6;
39     }printf("%d %d %.4f",a,b,l);
40     return 0;
41 }

 

以上是关于SUOI07 区间平均++ (二分答案+前缀和)的主要内容,如果未能解决你的问题,请参考以下文章

牛客多校4J二分答案连续子段最大平均值

csp-s模拟测试52平均数,序列题解

Part2.3 P1314 聪明的质检员 二分答案前缀和优化

聪明的质监员(二分答案,前缀和)

2021牛客暑期多校训练营4Average (二分答案,区间/子数组最大平均值,)

102. 最佳牛围栏