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 d(n+i=1ndai1)k+i=1nai

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

所以考虑枚举 d d d

#include
#include
#include 
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} x=k+i=1nai

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

#include
#include
#include 
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);
}

你可能感兴趣的:(分块运算,数论,暴力)