砍树
2018.8.25
林先森买了n棵树苗,种在一条直线上,用来装点他的花园。初始时所有树苗的高度是0,每过1天每棵树苗都会长高1米。对每棵树苗,林先森希望它的最终高度为ai,因此他会定时检查树苗的情况,并及时砍掉过高的树苗。具体来说,从种下所有树苗开始,每d天(即:第d天、第2d天,. . . ,以此类推)林先森会检查一遍所有的树苗,如果有树苗的高度不低于他希望的高度,林先森会把高出的部分(可以为0)砍掉,之后这棵树苗便不再长高。由于砍树是一件辛苦的工作,林先森希望砍掉的树苗的总长度不超过k米。在这个前提下,为了偷懒,林先森想要知道最大可能的d值。
Code:
#pragma GCC optimize(2)
#include<stdio.h>
#include<algorithm>
using namespace std;
#define N 200
#define ll long long
template<class T>
inline void read(T &x){
x=0;char c=getchar();T flag=1;
while(c<'0'||c>'9'){if(c=='-')flag=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-48;c=getchar();}
x*=flag;
}
ll n,k,a[N],b[N*N*N*2],cnt=0;
int main(){
freopen("cut.in","r",stdin);
freopen("cut.out","w",stdout);
read(n),read(k);
for(int i=1;i<=n;i++){
read(a[i]);
k+=a[i];
for(ll j=1;j*j<=a[i];j++){
b[++cnt]=j;
b[++cnt]=(a[i]-1)/j+1;
}
}
sort(b+1,b+1+cnt);
cnt=unique(b+1,b+1+cnt)-(b+1);
ll ans=1;
for(int i=1;i<=cnt;i++){
ll ret=0;
for(int j=1;j<=n;j++)
ret+=(a[j]-1)/b[i]+1;
ll mx=k/ret;
if(mx>=b[i]) ans=mx;
}
printf("%lld",ans);
}