题目
题目链接:https://www.luogu.com.cn/problem/P3708
Koishi 在 Flandre 的指导下成为了一名数学大师,她想了一道简单的数学题。
输入一个整数 (n),设 (displaystyle f(x) = sum_{i=1}^n x mod i),你需要输出 (f(1), f(2), ldots , f(n))。
按照套路,Koishi 假装自己并不会做这道题,就来求你帮忙辣。
思路
考虑每一个 (i) 作为模数的贡献。发现它对 (f) 造成的贡献是
[0,1,2,···,i-2,i-1,0,1,2,···i-2,i-1,···
]
也就是对于区间 ([ki,(k+1)i)) 是分别贡献了 (1sim i-1),设 (f) 一开始全部是 (1),可以枚举 (i) 的每一个倍数,在 (i) 倍数位置减去 (i),然后做一遍前缀和就是 (f) 了。
对于每一个 (i) 跑一遍,时间复杂度 (O(nlog n))。
思路
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1000010;
ll n,f[N];
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
for (int j=i;j<=n;j+=i)
f[j]-=i;
for (int i=1;i<=n;i++)
{
f[i]+=f[i-1]+n;
printf("%lld ",f[i]);
}
return 0;
}