题面
题目描述
科学家们在 Samuel 星球上的探险得到了丰富的能源储备,这使得空间站中大型计算机 Samuel II 的长时间运算成为了可能。由于在去年一年的辛苦工作取得了不错的成绩,小联被允许用 Samuel II 进行数学研究。
小联最近在研究和约数有关的问题,他统计每个正数 \(N\) 的约数的个数,并以 \(f(N)\) 来表示。例如 \(12\) 的约数有 \(1,2,3,4,6,12\),因此 \(f(12)=6\)。下表给出了一些 \(f(N)\) 的取值:
\(N\) | \(1\) | \(2\) | \(3\) | \(4\) | \(5\) | \(6\) |
---|---|---|---|---|---|---|
\(f(N)\) | \(1\) | \(2\) | \(2\) | \(3\) | \(2\) | \(4\) |
现在请你求出:
\[ \sum_{i=1}^n f(i) \]
输入输出格式
输入格式
输入一个整数 \(n\)。
输出格式
输出答案。
输入输出样例
输入样例 #1
3
输出样例 #1
5
说明
- 对于 \(20\%\) 的数据,\(N \leq 5000\);
- 对于 \(100\%\) 的数据,\(1 \leq N \leq 10^6\)。
分析
如果纯模拟的话,朴素做法自然是把\(n\)以内的数全都求一遍因数个数。求一个数的因数个数复杂度为\(O(\sqrt{i})\),那么这种朴素做法是\(O(n\sqrt{n})\)级别的。但我们可以有一种更优秀的做法。
动用我们聪明的大脑,就可以想出,我们还可以枚举\(i( 1 \le i \le n)\),求这个因数\(i\)在\(1 \sim n\)中出现了多少次。那么出现了多少次呢?大可不必在第二层枚举,结果就是\(\lfloor n/i \rfloor\),至于为什么?你想啊,一个因数\(i\)在\(1 \sim n\)中出现了多少次,其实就是在说\(n\)以内有多少个\(i\)的倍数,\(i\)的倍数每\(i\)个出现一次,答案自然是\(\lfloor n/i \rfloor\) 。所以我们就有了一种\(O(n)\)的做法:求
\[\sum_{i=1}^n\lfloor n/i \rfloor\]
代码实现就很简单了,但为了诚意贴个代码:
代码
/*
* @Author: crab-in-the-northeast
* @Date: 2020-02-24 16:52:07
* @Last Modified by: crab-in-the-northeast
* @Last Modified time: 2020-02-24 16:53:12
*/
#include <iostream>
#include <cstdio>
int n;
long long ans;
int main() {
scanf("%d",&n);
for(int i = 1; i <= n; i++) ans += n / i;
printf("%lld\n",ans);
return 0;
}
评测结果
AC 100
:R31016131