zoukankan      html  css  js  c++  java
  • CF505E Mr. Kitayuta vs. Bamboos

    看到陈指导写的标签就直接知道怎么做了,想到倒着做还是比较简单的

    首先最大值最小我们一眼二分答案(x),然后我们就发现那个(max(h_i-p,0))很难处理

    考虑倒着做,这样操作就变成了:

    • 初始时每个数都是(x)
    • (k)次,每次选择一个数加上(p)
    • 将所有数减去(a_i)

    最后要求做的过程中所有数都要大于等于(0)并且最后要超过(h_i)

    思考如何检验,我们发现此时我们可以把增加的操作攒起来一起加

    容易想到我们可以开一个,分别记录做(i)次操作后哪些位置会小于(0)

    枚举减的操作次数,将对应的桶内的元素需要的加上次数累加后重新计算扔进桶里即可

    由于加数操作在第(i)次不能超过(i imes k),因此检验一次复杂度就是(O(n+mk))

    综上,总复杂度(O((n+mk)log (p imes m)))

    #include<cstdio>
    #include<vector> 
    #define RI register int
    #define CI const int&
    #define int long long
    using namespace std;
    typedef vector <int>:: iterator VI;
    const int N=100005,M=5005;
    int n,m,k,p,h[N],a[N],s[N],ans; vector <int> v[M];
    inline void expand(CI x,CI y)
    {
    	if (x<m) v[x].push_back(y);
    }
    inline bool check(CI x)
    {
    	RI i; int sum=0; for (i=1;i<=m;++i) v[i].clear();
    	for (i=1;i<=n;++i) expand((s[i]=x)/a[i],i);
    	for (i=0;i<m;++i) for (VI it=v[i].begin();it!=v[i].end();++it)
    	{
    		int dlt=(a[*it]*(i+1)-s[*it]+p-1)/p;
    		if (s[*it]+=dlt*p,(sum+=dlt)>i*k) return 0; expand(s[*it]/a[*it],*it);
    	}
    	for (i=1;i<=n;++i) if (s[i]<a[i]*m+h[i])
    	if ((sum+=(a[i]*m+h[i]-s[i]+p-1)/p)>m*k) return 0; return 1;
    }
    signed main()
    {
    	RI i; for (scanf("%lld%lld%lld%lld",&n,&m,&k,&p),i=1;i<=n;++i)
    	scanf("%lld%lld",&h[i],&a[i]); int l=1,r=1e15,mid; while (l<=r)
    	if (check(mid=l+r>>1)) ans=mid,r=mid-1; else l=mid+1;
    	return printf("%lld",ans),0;
    }
    
  • 相关阅读:
    第八篇 Flask中的蓝图
    第七篇 Flask实例化配置及Flask对象配置
    第六篇 Flask中的路由系统
    第五篇 Flask 中内置的 Session
    第四篇 Flask 中的模板语言 Jinja2 及 render_template 的深度用法
    第三篇 Flask中的request
    守护进程与守护线程
    GIL(全局解释器锁)与互斥锁
    python 面向对象
    实现能计算类似1
  • 原文地址:https://www.cnblogs.com/cjjsb/p/14084009.html
Copyright © 2011-2022 走看看