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=1∑n⌊dai−1⌋)≤k+i=1∑nai

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

所以考虑枚举 d 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} x=k+i=1∑nai

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

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