CSP 2023 提高级第一轮 CSP-S 2023初试题 程序阅读第二题解析

一、题目阅读

#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(nlog⁡2n)

B. O(n)
C. O(nlog⁡n)
D. O(nlog⁡log⁡n)

【solve1函数的基于埃氏筛法,埃筛的时间复杂度是O(nloglogn)】

2. solve2(n) 的时间复杂度为(B)。

A. O(n^2)

B. O(n)

C. O(nlog⁡n)
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】

  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值