一、题目阅读
#include <iostream> #include <cmath> #include <vector> #include <algorithm> using namespace std; long long solve1(int n) { vector<bool> p(n + 1, true); vector<long long> f(n + 1, 0), g(n + 1, 0); f[1] = 1; for (int i = 2; i * i <= n; i++) { if (p[i]) { vector<int> d; for (int k = i; k <= n; k *= i) d.push_back(k); reverse(d.begin(), d.end()); for (int k : d) { for (int j = k; j <= n; j += k) { if (p[j]) { p[j] = false; f[j] = i; g[j] = k; } } } } } for (int i = sqrt(n) + 1; i <= n; i++) { if (p[i]) { f[i] = i; g[i] = i; } } long long sum = 1; for (int i = 2; i <= n; i++) { f[i] = f[i / g[i]] * (g[i] * f[i] - 1) / (f[i] - 1); sum += f[i]; } return sum; } long long solve2(int n) { long long sum = 0; for (int i = 1; i <= n; i++) { sum += i * (n / i); } return sum; } int main() { int n; cin >> n; cout << solve1(n) << endl; cout << solve2(n) << endl; return 0; }
二、题目解析
判断题
1. 将第 15 行删去,输出不变。(错)
【solve1()函数中内循环依赖d容器,如果删除一定影响结果,只是无意义地将d反转n次】
2. 当输入为
10
时,输出的第一行大于第二行。(错)【我们自己走一遍流程,发现输入10时,两个函数的返回相同,都为87(把每个数据都列出来)】
3.(2 分)当输入为
1000
时,输出的第一行与第二行相等。(对)【我们验证几个小规模的数据,发现除了零以外solve1()和solve2()的返回值一样,本题两个函数的返回值都为823081】
单选题
1
.solve1(n)
的时间复杂度为()。A. O(nlog2n)
B. O(n)
C. O(nlogn)
D. O(nloglogn)【solve1函数的基于埃氏筛法,埃筛的时间复杂度是O(nloglogn)】
2.
solve2(n)
的时间复杂度为(B)。A. O(n^2)
B. O(n)
C. O(nlogn)
D. O(nsqrt(n))【循环n次,O(n)】
3. 当输入为
5
时,输出的第二行为(B)。A. 20
B. 21
C. 22
D. 23【直接算,1*5+2*2+3*1+4*1+5*1 = 5+4+3+4+5 = 21】