GESP 五级 · GESP 202412 C++ 五级 第 8 题

选择题 · 答案 A · 考点:时间复杂度分析

← 整套速查表 GESP 五级 全部真题

题目

下述代码实现素数表的线性筛法,筛选出所有小于等于 $n$ 的素数。下面说法正确的是( )。

vector<int> sieve_linear(int n) {
    vector<bool> is_prime(n +1, true);
    vector<int> primes;

    for (int i = 2; i <= n/2; i++) {
        if (is_prime[i])
            primes.push_back(i);

        for (int j = 0; j < primes.size() && i * primes[j] <= n; j++) {
            is_prime[ i * primes[j] ] = 0;
            if (i % primes[j] == 0)
                break;
        }
    }

    for (int i = n/2 +1; i <= n; i++) {
        if (is_prime[i])
            primes.push_back(i);
    }

    return primes;
}
答案:A

考点

时间复杂度分析

解题思维

埃氏筛法:从2开始标记倍数为合数,O(n log log n)。线性筛(欧拉筛):每个合数只被最小质因子标记一次,O(n)。线性筛效率更高。

常见错误

分析复杂度时注意外层循环和内层循环的关联。例如内外两层都到n的循环不一定是O(n²),要看内层是否每次都在缩小。

详细解析(节选)

【考点】线性筛法|时间复杂度分析|埃氏筛对比

解题思维:代码本质是线性筛的变体——外层循环到 n/2 时,每个合数 i*primes[j] 仅当 primes[j] 是其最小质因子时才会被标记,若 i%primes[j]==0 则立即 break,保证每个合数只被筛一次。最后 n/2+1~n 的补充循环只是补上大质数,不影响复杂度。

陷阱拆解:A 正确,线性筛复杂度线性 O(n);B 错,每个合数仅被最小质因子筛一次,而非所有质因子;C 错,埃氏筛会重复标记(如 12 被 2 和 3 各筛一次),与线性筛核心思想不同;D 显然排除。

反命题思维:命题人刻意用 n/2 分界拆分循环,想考验你是否真正理解线性筛的"每个合数唯一标记"机制,而非机械记忆复杂度。改题:若把外层循环改为 i<=n,则时间复杂度仍为 O(n),但内层标记逻辑不变。

同考点真题

在 OI伴学 里做这道题
登录后可计时作答、查看完整六段式解析,并按你的错题自动生成同类练习。
去刷题先做一次 AI 学情诊断