枚举+整除技巧
对于一个x,它的答案是
∑ni=1(⌊aix⌋+aimodx)
把取模转化为乘除运算并且整理得
∑ni=1(ai+⌊aix⌋∗(1−x))
于是问题就变成如何快速求出 ⌊aix⌋ ,这正是我没想到的- -。我们发现随着 ai 增大, ⌊aix⌋ 是不降的,于是可以枚举取值,复杂度是log的。
附UOJ题解:http://vfleaking.blog.uoj.ac/blog/33
#include<cstdio>
#define N 1000005
using namespace std;
int a[N], cnt[N];
int main()
{
int n;
long long ans=1ll<<62, sum=0;
scanf("%d",&n);
for(int i = 1; i <= n; i++)
{
scanf("%d",&a[i]);
cnt[a[i]]++;
sum+=a[i];
}
for(int i = N-2; i; i--)
cnt[i]+=cnt[i+1];
for(int x = 1; x < N; x++)
{
long long temp=0;
for(int j = 1; 1.0 * j * x < N; j++)
temp+=cnt[j*x];
temp*=(1-x);
temp+=sum;
if(ans>temp)ans=temp;
}
printf("%lld\n",ans);
return 0;
}