题意:求\(x\)使得\(\sum\limits_{i=1}^{n}[a_i/x]+a_i\%x\)
首先把取余运算换成减法。提公因式。
\(\sum\limits_{i=1}^{n}[a_i/x]+a_i\%x=\sum\limits_{i=1}^{n}{[a_i/x]+a_i-x[a_i/x]}=\sum\limits_{i=1}^{n}a_i+\sum\limits_{i=1}^{n}{(1-x)[a_i/x]}\) 发现什么?枚举x,根据某个n/1+n/2+n/3+...+n/n=nlogn的式子,前缀和计算出后半部分的值。恰好a_i最大就是1e6,可以这么搞,估计这道题已经设计好a_i就是1e6的。小心溢出就可以了。
#includeusing namespace std;typedef long long ll;int n;int a[1000005]={};int pa[2000005]={};int maxa=0;ll sum=0;ll minans=0;int main() {#ifdef Yinku freopen("Yinku.in","r",stdin);#endif // Yinku scanf("%d",&n); for(int i=1;i<=n;i++){ int t; scanf("%d",&t); if(t>maxa) maxa=t; sum+=t; a[t]++; } for(int i=1;i<=maxa*2;i++){ pa[i]=pa[i-1]+a[i]; } for(int d=2;d<=maxa;d++){ ll tminans=0; int c=(maxa+d-1)/d; for(int j=1;j<=c;j++){ if(j*d>maxa) break; tminans+=1ll*(pa[(j+1)*d-1]-pa[j*d-1])*j; } tminans*=(1ll-d); if(minans>tminans) minans=tminans; } printf("%lld\n",sum+minans);}