noip 2018.10.14 模擬賽 砍樹
阿新 • • 發佈:2018-12-15
數學問題...
根據題意,有:
移項,整理,得:
記
於是
那麼
可以看到,最多隻會有2*個取值(顯而易見)
於是對應的,可能產生效果的d也只會有個,於是我們把他們找出來,扔進一個數組裡然後排序,去重,獲得的就是所有可能的取值
接下來,我們列舉所有取值,然後計算出左邊的表示式,那麼顯然,我們是可以求出最大的d的,那麼我們只需要求最大的這個d比列舉到的取值要大即可(否則顯然是不合法的啊)!
這樣問題就解決了
#include <cstdio> #include <cmath> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #include <queue> #include <stack> #define ll long long using namespace std; ll a[105]; ll n,k; ll fac[10000005]; int main() { freopen("cut.in","r",stdin); freopen("cut.out","w",stdout); scanf("%I64d%I64d",&n,&k); ll c=k; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); c+=a[i]; } int cnt=0; for(int i=1;i<=n;i++) { for(int j=1;j*j<=a[i];j++) { fac[++cnt]=j; fac[++cnt]=(a[i]-1)/j+1; } } sort(fac,fac+cnt+1); cnt=unique(fac,fac+cnt+1)-(fac+1); ll ans=1; for(int i=1;i<=cnt;i++) { ll temp=0; for(int j=1;j<=n;j++) { temp+=(a[j]-1)/fac[i]+1; } ll t=c/temp; if(t>=fac[i]) { ans=t; } } printf("%I64d\n",ans); return 0; }