最小化$\sum\limits{i=1}^{n}a[i]/x+a[i]\;mod\;x$
=$\sum\limits{i=1}^{n}(1-x)*(a[i]/x)+a[i]$
=$\sum\limits{i=1}^{n}a[i]-\sum\limits{i=1}^{n}(x-1)*a[i]/x$
直接枚举x,然后对于0~x-1这部分贡献是0,x~2x-1这部分贡献是1。
按x分块计算即可。
代码:
#include <cstdio> #include <cstring> #include <algorithm> #include <cstdlib> #include <cmath> using namespace std; typedef long long ll; #define N 2000050 inline char nc() { static char buf[100000],*p1,*p2; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; } int rd() { int x=0; char s=nc(); while(s<‘0‘||s>‘9‘) s=nc(); while(s>=‘0‘&&s<=‘9‘) x=(x<<3)+(x<<1)+s-‘0‘,s=nc(); return x; } int n,a[N],s[N],mx; ll solve(int x) { ll re=0; int i; for(i=x;i<=mx;i+=x) { re+=ll(i/x)*(s[i+x-1]-s[i-1]); } return re*(x-1); } int main() { n=rd(); int i; ll sum=0,ans=0; for(i=1;i<=n;i++) a[i]=rd(),mx=mx<a[i]?a[i]:mx,sum+=a[i],s[a[i]]++; int lim=mx<<1; for(i=1;i<=lim;i++) s[i]+=s[i-1]; for(i=1;i<=mx;i++) ans=max(ans,solve(i)); printf("%lld\n",sum-ans); }
原文地址:https://www.cnblogs.com/suika/p/9463095.html
时间: 2024-11-06 03:28:22