CF830C. Bamboo Partition(整除分块)

CF830C. Bamboo Partition(整除分块)

思路:

式子化简得:

d ( n + i = 1 n a i 1 d ) k + i = 1 n a i d(n+\sum\limits_{i=1}^n\lfloor\dfrac{a_i-1}{d}\rfloor)\le k+\sum\limits_{i=1}^n a_i

1.整除分块,因为 a i 1 d \lfloor\dfrac{a_i-1}{d}\rfloor 对于不同 d d 只有 a i 1 \sqrt{a_i-1} 个值。

所以考虑枚举 d d

#include<cstdio>
#include<cmath>
#include<algorithm> 
using namespace std;
typedef long long ll;
ll a[105];
int main(){
	int n;ll k,d=0,r=1,mx=0;
	scanf("%d%lld",&n,&k);
	for(int i=1;i<=n;i++)
		scanf("%lld",&a[i]),k+=a[i],mx=max(mx,--a[i]);
	for(int l=1;r<=mx;l=r+1){
		r=1e15;ll s=0;
		for(int j=1;j<=n;j++)
			if(a[j]>=l)
			s+=a[j]/l,r=min(r,a[j]/(a[j]/l));
		s=k/(s+n);
		if(s>=l) d=max(d,min(s,r)); 
	}
	if(k/n>mx) d=max(k/n,d);
	printf("%lld\n",d);
} 

2.因为左式必有一项小于等于 x = k + i = 1 n a i x=\sqrt{k+\sum\limits_{i=1}^n a_i}

考虑枚举所有 i [ 1 , x ] i\in[1,\sqrt{x}] 计算 i , x i i,\dfrac{x}{i} 是否满足情况即可。

#include<cstdio>
#include<cmath>
#include<algorithm> 
using namespace std;
typedef long long ll;
ll a[105],k,ans;
int n;
bool check(ll d){
	ll s=n;
	for(int i=1;i<=n;i++) s+=(a[i]-1)/d;
	return s*d<=k;
}
int main(){
	scanf("%d%lld",&n,&k);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]),k+=a[i];
	for(ll i=sqrt(k);i>=1;i--){
		if(check(i)) ans=max(ans,i);
		if(check(k/i)) ans=max(ans,k/i);
	}
	printf("%lld\n",ans);
}

猜你喜欢

转载自blog.csdn.net/weixin_45750972/article/details/107758232
今日推荐