题目
思路
先暴力推式子
\(\sum_{i=1}^{n}d-((a_i-1)\%d+1))\le k\)
看到\(\%\),直接转换成除法
\(\sum_{i=1}^{n}d-(a_i-d*\lfloor\frac{a_i-1}{d}\rfloor)\le k\)
\(\sum_{i=1}^{n}\lfloor\frac{a_i-1}{d}\rfloor\le \frac{k+\sum_{i=1}^na_i-n}{d}\)
考虑左边的式子,
根据整除分块的相关知识
我们设\(maxx=max(a_i)\)
左边的式子最多有\(\sqrt {maxx}*n\)种取值
如果要变化
每一次移动d一定会使某一项的值\(+1\)
对于每一个,最多会有\(\sqrt n\)次
所以总共的取值就有\(\sqrt {maxx}*n\)种
之后我们对左边进行整除分块,用右边的式子检验\(d\)是否合法即可
代码
#include<iostream>
using namespace std;
long long n,k;
long long a[105];
long long maxx;
long long ans;
int main()
{
cin>>n>>k;
for(int i=1;i<=n;i++)
{
cin>>a[i];
k+=a[i];
maxx=max(maxx,a[i]);
}
for(long long l=1,r,s;l<=maxx;l=r+1)
{
s=0;
r=(1ll<<60);
for(int i=1;i<=n;i++)
if(a[i]-1>=l)
r=min(r,(a[i]-1)/((a[i]-1)/l));
for(int i=1;i<=n;i++)
s+=(a[i]-1)/r+1;
long long t=k/s;
if(l<=t&&t<=r)
ans=max(ans,t);
l=r+1;
}
if(k/n>maxx)
ans=max(ans,k/n);
cout<<ans;
return 0;
}