码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces1355E Guess Divisors Count

时间:2020-05-23 16:41:34      阅读:67      评论:0      收藏:0      [点我收藏+]

标签:ons   const   signed   lower   guess   sig   view   ble   fine   

比较厉害的一个题目吧

Description

link

Solution

我们首先发现 \(M=min(M,A+R)\)

然后考虑二分做这个题

二分高度,考虑怎么 \(check\)

我们发现这个题对于一个已知的高度,怎么求花费呢?

把多于和少于高度 \(H\) 的砖的数目统计出来,然后这个数乘上 \(M\) 再加上缺少的乘 \(A\) 或者是多出来的乘 \(R\)

这么统计答案,随着给定 \(H\) 的增加,答案是个单谷的(可以手推一下……)

这个波谷在 \(\frac {sum} 2\) 或者 \(\frac{sum} 2+1\)

但是不要忘记把每个砖的高都作为最终高度算一下(防卡)

所以可能就不需要二分了

别忘了先 \(sort\)

复杂度:\(O(n\log n)\)

(居然复杂度又到了 \(sort\) 上)

Code

#include<bits/stdc++.h>
using namespace std;
#define int long long
namespace yspm{
	inline int read()
	{
		int res=0,f=1; char k;
		while(!isdigit(k=getchar())) if(k==‘-‘) f=-1;
		while(isdigit(k)) res=res*10+k-‘0‘,k=getchar();
		return res*f;
	}
	const int N=1e5+10;
	int n,a,r,m,h[N],sum[N],ans=1e15+10;
	inline int solve(int x)
	{
		int pos=lower_bound(h+1,h+n+1,x)-h-1,res=0;
		int c1=x*pos-sum[pos],c2=sum[n]-sum[pos]-x*(n-pos);
		res=min(c1,c2); c1-=res; c2-=res; res*=m;
		res+=c1*a+c2*r;
		return res;
	}
	signed main()
	{
		n=read(); a=read(); r=read(); m=read();
		m=min(m,a+r); 
		for(int i=1;i<=n;++i) h[i]=read();
		sort(h+1,h+n+1);
		for(int i=1;i<=n;++i) sum[i]=sum[i-1]+h[i];
		ans=min(solve(sum[n]/n+1),solve(sum[n]/n));
		for(int i=1;i<=n;++i) ans=min(ans,solve(h[i]));
		printf("%lld\n",ans);
		return 0;
	}
}
signed main(){return yspm::main();}

Review

记得 \(dp\) 碰壁的时候想想贡献二分啥的

Codeforces1355E Guess Divisors Count

标签:ons   const   signed   lower   guess   sig   view   ble   fine   

原文地址:https://www.cnblogs.com/yspm/p/12942767.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!