题目链接
题意分析
\[\sum_{i=1}^nx\%i=\sum_{i=1}^n(x-\lfloor\frac{x}{i}\rfloor i)=nx-\sum_{i=1}^n\lfloor\frac{x}{i}\rfloor i
\]
想到了整除分块 这样的话复杂度\(O(n\sqrt{n})\) 但是由于\(n≤10^6\) 所以我们要想出来一个更优的方法
我们考虑一下 从\(f(x)\)到\(f(x+1)\)的时候 \(\sum_{i=1}^n\lfloor\frac{x}{i}\rfloor i\)成为了\(\sum_{i=1}^n\lfloor\frac{x+1}{i}\rfloor i\)
同时\(x+1\)与\(x\)是互质的 所以\(x+1\)的约数肯定不是\(x\)的约数(1除外) 所以\(x\)到\(x+1\)之后\(x+1\)的约数在下取整符号里面的值也会+1
那么再乘i之后的相当于就是增加了\(x+1\)的约数和
所以我们可以求出\(1-n\)所有数的约数和 然后做一个前缀和 就是\(\sum_{i=1}^n\lfloor\frac{x}{i}\rfloor i\)
求约数和我们可以使用线性筛 但是这里的话 使用调和级数的复杂度就可以了
CODE:
#include<bits/stdc++.h>
#define M 1008611
using namespace std;
int n;
long long sum[M];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
for(int j=i;j<=n;j+=i)
sum[j]+=i;
for(int i=1;i<=n;++i) sum[i]+=sum[i-1];
for(int i=1;i<=n;++i)
printf("%lld%c",(long long)n*(long long)i-sum[i],(i==n ? '\n':' '));;
return 0;
}