P3708 koishi的数学题


题目链接

题意分析

\[\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
#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;
} 

相关