acm-(二分)2020ICPC·小米 网络选拔赛第一场 F.Design Problemset

题面
传送门
考虑二分次数最大值,也就是答案。考虑如何check,对于第 i i i个物体而言,它在每次中一定至少被分配 ⌊ a [ i ] x ⌋ \lfloor \frac {a[i]}{x}\rfloor xa[i]个,同时最终会剩下 a [ i ] % x a[i]\%x a[i]%x个物品给我们灵活分配,现在设置一个变量 d i v = ∑ i = 1 k ⌊ a [ i ] x ⌋ div=\sum_{i=1}^k\lfloor \frac {a[i]}{x}\rfloor div=i=1kxa[i],再设置一个变量 r e s = ∑ i = 1 k a [ i ] % x res=\sum_{i=1}^ka[i]\%x res=i=1ka[i]%x,不过由于限制了第 i i i个物体的取值范围在 [ l [ i ] , r [ i ] ] [l[i],r[i]] [l[i],r[i]],因此当 ⌊ a [ i ] x ⌋ < l [ i ] \lfloor \frac {a[i]}{x}\rfloor<l[i] xa[i]<l[i]意味着不管怎样都没办法分配下去,这时候return false即可,不过当 ⌊ a [ i ] x ⌋ > r [ i ] \lfloor \frac {a[i]}{x}\rfloor >r[i] xa[i]>r[i],我们不能让 d i v + = ⌊ a [ i ] x ⌋ div+=\lfloor \frac{a[i]}x\rfloor div+=xa[i],此时我们让 d i v div div加上 r [ i ] r[i] r[i]即可,同时注意此时该物品没有可以灵活分配的余项了,也就是 r e s + = 0 res+=0 res+=0
最终求出来的 d i v div div代表除去灵活分配的 r e s res res那一部分外,每次所有物品能够分配的最大数目之和,这些数目如果小于 L L L,别急着return false,我们还要考虑可以灵活分配的 r e s res res,我们将它除以 x x x,也就是 ⌊ r e s x ⌋ \lfloor \frac {res}x\rfloor xres,这一项代表着每一次中我们都还可以选择 ⌊ r e s x ⌋ \lfloor \frac {res}x\rfloor xres个物品让它们的分配名额 + 1 +1 +1,这也是我们最大化物品数目之和的措施,不过剩下的 r e s % x res\%x res%x就没有任何作用了,因为它不能给 x x x次的物品分配都产生贡献。

因此在 x x x次的条件下,我们能够做到最大化的物品数量之和为 d i v + ⌊ r e s x ⌋ div+\lfloor\frac{res}x\rfloor div+xres。如果这个数仍然小于 L L L,就return false,否则return true,注意本题题目中并不要求用完所有的物品

然后一开始我们需要做一个特判,如果满足 ∑ i l [ i ] > R \sum_il[i]>R il[i]>R ∑ i r [ i ] < L \sum_{i}r[i]<L ir[i]<L直接输出0即可。

这列给出一份参考代码:

int k,L,R;
int a[maxn],mi[maxn],mx[maxn];

bool check(ll x){
	ll res=0,div=0,cur=0,cre;
	if(!x)return true;
	FOR(i,0,k){
		cur=a[i]/x,cre=a[i]%x;
		if(cur<mi[i])return false;
		if(cur>mx[i])cur=mx[i],cre=0;
		res+=cre;
		div+=cur;
	}
	return div+res/x>=L;
}
int main(){
	k=rd(),L=rd(),R=rd();
	FOR(i,0,k)a[i]=rd();
	ll sm1=0,sm2=0;
	FOR(i,0,k)mi[i]=rd(),mx[i]=rd(),sm1+=mi[i],sm2+=mx[i];
	if(sm1>R || sm2<L)return wrn(0),0;
	ll l=0,r=1e14,ans=0;
	while(l<=r){
		ll mid=l+r>>1ll;
		if(check(mid)){
			l=mid+1;
			ans=mid;
		}else r=mid-1;
	}
	wrn(ans);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值