zoukankan      html  css  js  c++  java
  • Luogu P1404 平均数 题解

    闲扯

    蒟蒻又来做例题了。。。

    这道题调了半天,结果是维护前缀和的最小值的时候弄成了原数组的值。。。。

    题面

    题面

    Solution

    使用二分答案,将求解转化为判定。

    对于当前二分出的平均值,我们要确定它的合法性,我们可以将所有数先减去平均值。

    这时我们相当于是要找去一段区间,使得它的和大于 (0)

    我们慢慢来解决这个问题。

    1. 对于没有长度限制,找出一个区间,使它的和最大。

      ​ 这是一个经典问题,只需要 (O(n)) 扫描这个区间,将新的数加入子段。当和为负值,就将子段清空。扫描过程中出现的最大子段和即为所求。

    2. 对于有长度限制,找出一个区间,使它的和最大。

      ​ 子段和转化为前缀和相减,则有: (maxlimits_{i-jgeq L}(A_{j+1},A_{j+1},cdots,A_i)=maxlimits_{Lleq ileq n}(sum_i-minlimits_{0leq jleq i-L} sum_j))

      ​ 随着 (i) 的增长, (j) 的取值范围每次只会增加 (1) 。所以我们每次更新一下最小值即可。

    Code

    #include<bits/stdc++.h>
    #define del(a,i) memset(a,i,sizeof(a))
    #define ll long long
    #define inl inline
    #define il inl void
    #define it inl int
    #define ill inl ll
    #define re register
    #define ri re int
    #define rl re ll
    #define mid ((l+r)/2)
    #define lowbit(x) (x&(-x))
    #define INF 0x3f3f3f3f
    using namespace std;
    template<class T>il read(T &x){
    	int f=1;char k=getchar();x=0;
    	for(;k>'9'||k<'0';k=getchar()) if(k=='-') f=-1;
    	for(;k>='0'&&k<='9';k=getchar()) x=(x<<3)+(x<<1)+k-'0';
    	x*=f;
    }
    template<class T>il print(T x){
    	if(x/10) print(x/10);
    	putchar(x%10+'0');
    }
    ll mul(ll a,ll b,ll mod){long double c=1.;return (a*b-(ll)(c*a*b/mod)*mod)%mod;}
    it qpow(int x,int m,int mod){
    	int res=1,bas=x%mod;
    	while(m){
    		if(m&1) res=(res*bas)%mod;
    		bas=(bas*bas)%mod,m>>=1;
    	}
    	return res%mod;
    }
    const int MAXN = 1e5+5;
    int n,m,val[MAXN];
    double sum[MAXN],a[MAXN],l,r=2000.,eps=1e-5;
    inl bool check(double lim){
    	for(ri i=1;i<=n;++i) a[i]=val[i]-lim,sum[i]=sum[i-1]+a[i];
    	double ans=-1e10,mn=1e10;
    	for(ri i=m;i<=n;++i){
    		mn=min(mn,sum[i-m]);
    		ans=max(ans,sum[i]-mn);
    	}
    	return ans>=0;
    }
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	read(n),read(m);
    	for(ri i=1;i<=n;++i) read(val[i]);
    	while(l+eps<r){
    		if(check(mid)) l=mid;
    		else r=mid;
    	}
    	print(int(r*1000));
    	return 0;
    }
    

    总结

    对于不同的二分的模板一定要记清楚,不然考试打炸了就。。。。

  • 相关阅读:
    携程机票实时数据处理实践及应用
    关系型数据库表设计
    tornado
    Poisson distribution 泊松分布 指数分布
    Interpret bytes as packed binary data
    python爬虫爬取内容中,-xa0,-u3000的含义
    Okapi BM25 (BM stands for Best Matching)
    一主
    分片 副本
    暂时无法提交申请 帐号类型修改
  • 原文地址:https://www.cnblogs.com/TheShadow/p/11425959.html
Copyright © 2011-2022 走看看