GESP 客观题评测系统

2025 洛谷 SCP-J 第一轮模拟题(入门级 C++)

CSPJ-2025-R1-Mock-Luogu

试卷解析总览,可直接查看每题答案与解析。

一、单项选择题

(共 15 题,每题 2 分,共计 30 分;每题有且仅有一个正确选项)

1 题(单选题2 分)

GNU GCC 是常用的 C/C++ 语言编译器。现需要使用 `g++` 将 `luogu.cpp` 编译为可执行文件 `luogu`,可以使用编译命令( )。

A.
g++ -S luogu luogu.cpp
B.
g++ -S luogu.cpp luogu
C.
g++ -o luogu luogu.cpp
D.
g++ -o luogu.cpp luogu

正确答案C

解析详情

【答案】C

【考点】GCC 编译命令

【解析】 `-o luogu` 指定输出文件名为 `luogu`,最后的 `luogu.cpp` 是待编译源文件,因此命令应为 `g++ -o luogu luogu.cpp`。

【易错点】 `-S` 只生成汇编代码,不能直接得到题目要求的可执行文件。

2 题(单选题2 分)

关于编译语言与解释语言,以下说法错误的是( )。

A.
C++ 语言是编译语言,需要先经过编译得到可执行程序,才能交由机器执行。
B.
编译语言程序每一次执行都需要重新编译。
C.
解释器负责将解释语言的源程序翻译为可以执行的机器代码。
D.
Python 是常见的解释语言。

正确答案B

解析详情

【答案】B

【考点】编译语言与解释语言

【解析】 编译后的可执行文件可以反复运行;只有源代码改变或构建条件变化时才需要重新编译,所以 B 错误。

【易错点】 不要把“运行前需要编译”误解为“每次运行都要重新编译”。

3 题(单选题2 分)

阅读下面的代码,若输入的 `x` 是 1 至 10 范围内的正整数,输出不可能是( )。

#include <iostream>
using namespace std;

int main() {
    int x;
    cin >> x;
    switch (x) {
        case 1: { cout << "A"; break; }
        case 3: { cout << "C"; }
        default: { cout << "Q"; }
        case 5: { cout << "E"; }
    }
    return 0;
}
A.
A
B.
CQE
C.
QE
D.
Q

正确答案D

解析详情

【答案】D

【考点】switch 贯穿执行

【解析】 输入 1 输出 `A`;输入 3 从 `case 3` 贯穿得到 `CQE`;其他未匹配值从 `default` 贯穿得到 `QE`,输入 5 则输出 `E`。单独的 `Q` 不会出现。

【易错点】 `default` 后没有 `break`,还会继续执行后面的 `case 5`。

4 题(单选题2 分)

kkk>4k>4)进制数 43214321 与十进制数( )相等。

A.
43214321
B.
4k4+3k3+2k2+k4k^4+3k^3+2k^2+k
C.
4k3+3k2+2k+14k^3+3k^2+2k+1
D.
10k10k

正确答案C

解析详情

【答案】C

【考点】进制展开

【解析】 kk 进制的 43214321 按位权展开为 4k3+3k2+2k+14k^3+3k^2+2k+1

【易错点】 最高位的位权是 k3k^3,不是 k4k^4

5 题(单选题2 分)

阅读以下代码片段。当代码片段执行完毕后,`ans` 的值为( )。

int N = 10, ans = 0, x = 0;
for (int i = 1; i <= N; i++) {
    for (int j = i + 1; j <= N; j++) {
        ans += ++x;
    }
}
A.
45
B.
55
C.
990
D.
1035

正确答案D

解析详情

【答案】D

【考点】循环计数与等差数列

【解析】 内层循环共执行 9+8++1=459+8+\cdots+1=45 次,`x` 依次取 1 到 45,故 `ans=1+2+\cdots+45=1035`。

【易错点】 `ans` 累加的是递增后的 `x`,不是只统计循环次数。

6 题(单选题2 分)

给定一个空栈,支持入栈和出栈操作。将 1 至 10 依次入栈,第一个出栈的数为 8,则第二个出栈的数不可能为( )。

A.
1
B.
7
C.
9
D.
10

正确答案A

解析详情

【答案】A

【考点】栈的出栈序列

【解析】 首次弹出 8 后,栈顶是 7;此后可以直接弹出 7,也可以先压入并弹出 9 或 10,但不可能越过 7 到 2 而让 1 第二个出栈。

【易错点】 栈遵循后进先出,尚未弹出的 2~7 会挡在 1 上方。

7 题(单选题2 分)

有序表中有 100 个元素,使用二分法查找元素 X。有( )个数可以通过恰好 5 次查找找到。

A.
100
B.
32
C.
31
D.
16

正确答案D

解析详情

【答案】D

【考点】二分查找

【解析】 二分查找的比较过程形成二叉判定树,第 5 层有 24=162^{4}=16 个位置,因此恰好比较 5 次找到的元素有 16 个。

【易错点】 题目问的是恰好 5 次,不是最多 5 次。

8 题(单选题2 分)

下面的表格是无向图 G 的邻接矩阵,图 G 中度最大的点的度为( )。

  A B C D E
A 0 1 1 0 1
B 1 0 1 0 0
C 1 1 0 1 1
D 0 0 1 0 1
E 1 0 1 1 0
A.
1
B.
2
C.
3
D.
4

正确答案D

解析详情

【答案】D

【考点】邻接矩阵与顶点度

【解析】 无向图中顶点的度等于邻接矩阵对应行中 1 的个数;C 行有 4 个 1,为最大值。

【易错点】 不要把矩阵总边数或列数当作单个顶点的度。

9 题(单选题2 分)

8 支队伍均分为第一组与第二组进行小组赛。A 队和 B 队在同一组,而与 C 队不在同一组的分组方案数有( )种。

A.
10
B.
20
C.
30
D.
40

正确答案B

解析详情

【答案】B

【考点】组合计数

【解析】 第一、第二组有标签。A、B 可同在任一组,再从除 C 外的 5 支队伍中选 2 支同组,方案数为 2(52)=202\binom{5}{2}=20

【易错点】 若把两个小组当成无标签集合,会少乘一个 2。

10 题(单选题2 分)

将一根长度为 3 的木棍折为三段,当断点的位置在木棍中等概率分布时,三段木棍可以构成三角形的概率为( )。

A.
1
B.
0.5
C.
0.25
D.
0.125

正确答案C

解析详情

【答案】C

【考点】几何概率

【解析】 两个断点把长度归一化后,三段能成三角形等价于最长一段小于 1/21/2;在两个断点的单位正方形样本空间中,满足条件区域面积占 1/41/4

【易错点】 仅满足三段长度和固定还不够,必须检查最长边小于其余两边之和。

11 题(单选题2 分)

下列关于快速排序的说法中,不正确的是( )。

A.
快速排序典型地应用了分治法的思想。
B.
快速排序的最坏时间复杂度为 O(nlogn)O(n\log n)
C.
快速排序是基于交换的排序。
D.
`sort` 函数是 STL 提供的快排函数,同时结合了堆排序、插入排序等技术。

正确答案B

解析详情

【答案】B

【考点】快速排序复杂度

【解析】 快速排序在划分极不均衡时会退化为 T(n)=T(n1)+O(n)T(n)=T(n-1)+O(n),最坏时间复杂度是 O(n2)O(n^2),因此 B 不正确。

【易错点】 平均 O(nlogn)O(n\log n) 不能替代最坏复杂度。

12 题(单选题2 分)

关于整数的各种 8 位二进制编码方法,说法错误的是( )。

A.
-17 的原码为 `10010001`。
B.
22 的补码为 `00010110`。
C.
-13 的反码为 `11110010`。
D.
以上说法存在错误。

正确答案D

解析详情

【答案】D

【考点】原码、反码与补码

【解析】 -17 的原码是 `10010001`,22 的补码是 `00010110`,-13 的反码是 `11110010`,A、B、C 均正确,所以“以上说法存在错误”本身错误。

【易错点】 负数原码、反码和补码的转换规则不同。

13 题(单选题2 分)

表达式 (x2x1/2)4(x-2x^{-1/2})^4 中,xx 的系数为( )。

A.
12
B.
-12
C.
24
D.
-24

正确答案C

解析详情

【答案】C

【考点】二项式展开

【解析】 取两次 2x1/2-2x^{-1/2} 时幂次为 x2x1=xx^{2}\cdot x^{-1}=x,其系数为 (42)(2)2=24\binom{4}{2}(-2)^2=24

【易错点】 先用幂次条件确定选取次数,再计算组合系数和符号。

14 题(单选题2 分)

二叉树 T 的中序遍历为 `CGEADBF`,后序遍历为 `GECDFBA`,则其前序遍历为( )。

A.
ACEGBDF
B.
ACGEBDF
C.
ABDFCEG
D.
ABCDEFG

正确答案A

解析详情

【答案】A

【考点】二叉树遍历还原

【解析】 后序末尾确定根为 A;由中序划分可还原左子树前序为 `CEG`、右子树前序为 `BDF`,所以整树前序为 `ACEGBDF`。

【易错点】 每次都应先用后序序列末尾找根,再按中序序列分割左右子树。

15 题(单选题2 分)

2024 年,来自谷歌 DeepMind 的米斯·哈萨比斯和约翰·江珀获得了( ),以表彰他们在人工智能方面的贡献。

A.
王选奖
B.
图灵奖
C.
诺贝尔奖
D.
贝尔奖

正确答案C

解析详情

【答案】C

【考点】科技奖项

【解析】 米斯·哈萨比斯和约翰·江珀获得了 2024 年诺贝尔化学奖,因此选择“诺贝尔奖”。

【易错点】 图灵奖是计算机科学奖项,但题目所述 2024 年奖项是诺贝尔奖。

二、阅读程序(1)

#include <bits/stdc++.h>
using namespace std;

int main() {
    int l, r;
    cin >> l >> r;
    int cnt = 0;
    long long sum = 0;
    for (int i = l; i <= r; ++i) {
        if ((i & (i - 1)) != 0) {
            cnt += 1;
            sum += i;
        }
    }
    cout << cnt << " " << sum << endl;
    return 0;
}

假设输入的 `l` 和 `r` 均为不超过 10610^6 的正整数,且满足 lrl\le r,完成下面的判断题和单选题。

16 题(判断题1.5 分)

当输入为 `2 5` 时,程序的输出为 `2 8`。( )

正确答案正确

解析详情

【答案】正确

【考点】位运算判定 2 的幂

【解析】 条件 `(i & (i - 1)) != 0` 选中非 2 的幂。区间 2~5 中只有 3、5 被计入,数量为 2、和为 8。

【易错点】 2 和 4 是 2 的幂,不会进入 `if`。

17 题(判断题1.5 分)

程序的输出总是两个正整数。( )

正确答案错误

解析详情

【答案】错误

【考点】边界输出

【解析】 若区间只包含一个 2 的幂,例如输入 `1 1`,没有元素被计入,程序输出 `0 0`,并非两个正整数。

【易错点】 0 是非负整数,但不是正整数。

18 题(判断题1.5 分)

将第 8 行的 `long long` 改为 `int`,程序行为不变。( )

正确答案错误

解析详情

【答案】错误

【考点】整数溢出

【解析】 当区间较大时,被累加元素的和可接近 101210^{12},超过 32 位 `int` 上限;改成 `int` 会发生溢出,程序行为会改变。

【易错点】 `i` 不超过 10610^6 不代表许多个 `i` 的总和也能放进 `int`。

19 题(单选题3 分)

当输入为 `1 100` 时,程序的输出为( )。

A.
`93 4923`
B.
`92 4823`
C.
`93 4823`
D.
`92 4923`

正确答案A

解析详情

【答案】A

【考点】区间统计

【解析】 1~100 共 100 个数,其中 2 的幂有 1、2、4、8、16、32、64 共 7 个;故 `cnt=93`,`sum=5050-127=4923`。

【易错点】 1 也满足 2 的幂判定,应从计数和总和中排除。

20 题(单选题3 分)

当输入为 `10000 1000000` 时,程序的第一个输出为( )。

A.
989993
B.
989994
C.
989995
D.
989996

正确答案C

解析详情

【答案】C

【考点】2 的幂计数

【解析】 区间共有 100000010000+1=9900011000000-10000+1=990001 个数,其中 2 的幂为 2142^{14}2192^{19} 共 6 个,因此首个输出为 9900016=989995990001-6=989995

【易错点】 区间端点都包含在循环范围内。

二、阅读程序(2)

#include <bits/stdc++.h>
using namespace std;

int main() {
    int n, m;
    cin >> n >> m;
    vector<int> a(n);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    vector<int> dp(m + 1);
    dp[0] = 0;
    for (int i = 1; i <= m; ++i) {
        int now = 0;
        for (int j = 0; j < n; ++j) {
            if (i >= a[j] && dp[i - a[j]] == 0) {
                now = a[j];
            }
        }
        dp[i] = now;
    }
    cout << dp[m] << endl;
    return 0;
}

假设输入的 `n` 和 `m` 均为不超过 1000 的正整数,输入的 `a[i]` 均为不超过 `m` 的正整数,完成下面的判断题和单选题。

21 题(判断题1.5 分)

当输入为 `3 5 1 3 4` 时,程序的输出为 0。( )

正确答案错误

解析详情

【答案】错误

【考点】动态规划状态模拟

【解析】 依次计算得到 `dp[0..5] = 0,1,0,3,4,3`,所以最终输出 `dp[5]=3`,不是 0。

【易错点】 `now` 会被后面满足条件的 `a[j]` 覆盖。

22 题(判断题2 分)

当输入的数组 `a` 为 `{1}` 且 `m` 为偶数时,程序的输出为 0。( )

正确答案正确

解析详情

【答案】正确

【考点】奇偶状态

【解析】 当 `a={1}` 时,`dp[i]` 只依赖 `dp[i-1]`:奇数位置为 1,偶数位置为 0,因此偶数 `m` 输出 0。

【易错点】 `dp[0]=0` 使状态从 0 和 1 交替开始。

23 题(判断题1.5 分)

将第 16 行的条件 `i >= a[j] && dp[i - a[j]] == 0` 改为 `dp[i - a[j]] == 0`,程序可能会产生编译错误。( )

正确答案错误

解析详情

【答案】错误

【考点】数组越界与编译

【解析】 删除 `i >= a[j]` 后,`i<a[j]` 时会访问负下标;代码仍可通过编译,但运行时发生越界和未定义行为,因此不是编译错误。

【易错点】 能否编译与运行时下标是否合法是两件事。

24 题(单选题3 分)

当输入为 `4 13 1 2 3 4` 时,程序的输出为( )。

A.
0
B.
1
C.
2
D.
3

正确答案D

解析详情

【答案】D

【考点】取石子状态

【解析】 可选步长为 1~4 时,输态是 5 的倍数;133(mod5)13\equiv3\pmod5,最后一个能从输态 10 转移来的步长为 3,所以输出 3。

【易错点】 程序输出的是最后记录的可行步长,不是胜负布尔值。

25 题(单选题3 分)

当输入为 `7 1000 1 2 3 4 5 6 7` 时,程序的输出为( )。

A.
0
B.
1
C.
2
D.
3

正确答案A

解析详情

【答案】A

【考点】周期状态

【解析】 步长为 1~7 时,输态是 8 的倍数。1000 能被 8 整除,因此 `dp[1000]=0`。

【易错点】 连续可选 1~7 时状态周期为 8。

26 题(单选题4 分)

当输入的数组 `a` 为 `{1,2,3,4,5}` 时,有( )个符合数据范围的整数 `m` 使得输出为 3。

A.
165
B.
166
C.
167
D.
168

正确答案B

解析详情

【答案】B

【考点】周期计数与数据范围

【解析】 步长为 1~5 时,输出 3 恰在 m3(mod6)m\equiv3\pmod6。又因数组元素 5 必须不超过 `m`,需排除 m=3m=3;从 9 到 999 共 (9999)/6+1=166(999-9)/6+1=166 个。

【易错点】 不能忽略题设中的 `a[i] <= m`,否则会多算 `m=3`。

二、阅读程序(3)

#include <bits/stdc++.h>
using namespace std;

vector<int> primes;
int comp_by[2000005];

void sieve(int n) {
    for (int x = 2; x <= n; x++) {
        if (comp_by[x] == 0)
            primes.push_back(x);
        for (int i = 0; i < primes.size(); i++) {
            if (x * primes[i] > n) break;
            comp_by[x * primes[i]] = primes[i];
            if (x % primes[i] == 0) break;
        }
    }
}

int main() {
    freopen("input.txt", "w", stdout);
    freopen("output.txt", "r", stdin);
    int n;
    cin >> n;
    sieve(n);
    for (int i = 1; i <= n; i++)
        cout << comp_by[i] << ' ';
    return 0;
}

假设输入的 `n` 是不超过 10610^6 的正整数,完成下面的判断题和选择题。

提示:伯特兰-切比雪夫定理:对任意 n>1n>1,存在质数 pp 使得 n<p<2nn<p<2n

27 题(判断题1.5 分)

程序将从 `input.txt` 读入数据,输出到 `output.txt`。( )

正确答案错误

解析详情

【答案】错误

【考点】freopen 重定向

【解析】 第一条把标准输出以写模式重定向到 `input.txt`,第二条把标准输入以读模式重定向到 `output.txt`,方向与题目描述正好相反。

【易错点】 `freopen` 的第三个参数决定重定向的是 `stdin` 还是 `stdout`。

28 题(判断题1.5 分)

交换程序的第 12 行和第 13 行,不会导致数组越界。( )

正确答案正确

解析详情

【答案】正确

【考点】数组边界

【解析】 交换后会先写 `comp_by[x*primes[i]]` 再判断是否大于 `n`;首次越过 `n` 时乘数至多为 2,故下标不超过 2n20000002n\le2000000,仍小于数组长度 2000005。

【易错点】 越过筛选上界 `n` 不等于越过实际数组容量。

29 题(判断题1.5 分)

对于所有正整数 `i`,满足 1in1\le i\le n,输出的第 `i` 个数是 0 当且仅当 `i` 是质数。( )

正确答案错误

解析详情

【答案】错误

【考点】质数筛与特殊值 1

【解析】 筛法中质数位置保持 0,但 `comp_by[1]` 也为 0,而 1 不是质数,所以“当且仅当”不成立。

【易错点】 检验全称命题时不能漏掉范围内的特殊值 1。

30 题(单选题3 分)

该程序的主要流程最接近( )。

A.
递归法
B.
动态规划
C.
埃拉托斯特尼筛
D.
欧拉筛

正确答案D

解析详情

【答案】D

【考点】欧拉筛

【解析】 程序按质数表枚举并在遇到 `x` 的最小质因子时停止,使每个合数按其最小质因子生成一次,属于欧拉筛。

【易错点】 埃拉托斯特尼筛通常从每个质数的倍数出发统一标记。

31 题(单选题3 分)

将程序的第 14 行移动到第 11 行,当输入为 1000000 时,输出的第( )个数会发生改变。

A.
75
B.
45
C.
97
D.
105

正确答案B

解析详情

【答案】B

【考点】欧拉筛语句顺序

【解析】 把整除判断移到赋值之前后,`x=15` 遇到质数 3 会先退出,45 不再被标记,故第 45 个输出改变;75、105 仍可由更早的乘积标记,97 本来就是质数。

【易错点】 原顺序必须先标记 `x*p`,再在 `p` 整除 `x` 时退出。

32 题(单选题4 分)

当输入为 100 时,输出的所有数字之和为( )。

A.
154
B.
194
C.
197
D.
214

正确答案C

解析详情

【答案】C

【考点】最小质因子求和

【解析】 `comp_by` 保存合数的最小质因子。100 以内贡献分别为:偶合数 49×2=9849\times2=98,最小质因子为 3、5、7 的奇合数贡献 48、30、21,总和为 197。

【易错点】 质数和 1 的数组值都是 0,不应把它们本身加入总和。

三、完善程序(1)

(全排列检查)给定长度为 `n` 的数组 `a`,判断其是否构成全排列。如果 1,2,,n1,2,\ldots,n 都恰好在数组 `a` 中出现且仅出现一次,那么就称这个数组是一个全排列。

试补全程序。

#include <bits/stdc++.h>
using namespace std;

bool is_permutation(vector<int> &a) {
    int n = /* ① */;
    vector<int> count(/* ② */);
    for (int i = 0; i < n; i++) {
        if (/* ③ */)
            count[a[i]]++;
        else
            /* ④ */;
    }
    for (int i = 1; i <= n; i++)
        if (count[/* ⑤ */] > 1)
            return false;
    return true;
}

int main() {
    int n;
    cin >> n;
    vector<int> a(n);
    for (int i = 0; i < n; i++)
        cin >> a[i];
    if (is_permutation(a))
        cout << "The sequence is a permutation.";
    else
        cout << "The sequence is not a permutation.";
    return 0;
}

33 题(单选题3 分)

① 处应填( )。

A.
a.length()
B.
a.size()
C.
a.back()
D.
a.capacity()

正确答案B

解析详情

【答案】B

【考点】vector 长度

【解析】 形参 `a` 是 `vector<int>`,元素个数由 `a.size()` 返回,因此 ① 填 `a.size()`。

【易错点】 `capacity()` 是已分配容量,不一定等于实际元素个数。

34 题(单选题3 分)

② 处应填( )。

A.
0
B.
n
C.
n + 1
D.
1000000000

正确答案C

解析详情

【答案】C

【考点】计数数组下标

【解析】 程序会访问 `count[1]` 到 `count[n]`,所以需要 `n+1` 个元素,合法下标为 0~n。

【易错点】 若只开 n 个元素,访问 `count[n]` 会越界。

35 题(单选题3 分)

③ 处应填( )。

A.
1 <= a[i] && a[i] <= n
B.
1 <= a[i] <= n
C.
1 <= a[i] || a[i] <= n
D.
a[i] < 1 || a[i] > n

正确答案A

解析详情

【答案】A

【考点】C++ 范围判断

【解析】 合法值必须同时满足 `1 <= a[i]` 和 `a[i] <= n`,应使用逻辑与连接两个比较。

【易错点】 C++ 不支持数学式的链式比较,`1 <= a[i] <= n` 会被分两次求值。

36 题(单选题3 分)

④ 处应填( )。

A.
break
B.
continue
C.
return true
D.
return false

正确答案D

解析详情

【答案】D

【考点】异常输入处理

【解析】 一旦发现元素不在 1~n 范围内,数组不可能是全排列,应立即 `return false`。

【易错点】 `break` 或 `continue` 都可能让非法数组进入后续检查并被误判。

37 题(单选题3 分)

⑤ 处应填( )。

A.
i
B.
a[i]
C.
i - 1
D.
i / 2

正确答案A

解析详情

【答案】A

【考点】频次检查

【解析】 循环变量 `i` 正在枚举数值 1~n,应检查对应的 `count[i]` 是否大于 1,所以 ⑤ 填 `i`。

【易错点】 此处的 `i` 是数值下标,不是原数组的位置。

三、完善程序(2)

(跳跃)给定一个数组 a[0],a[1],,a[n1]a[0],a[1],\ldots,a[n-1],每次跳跃从当前位置 `x` 跳至位置 `a[x]`。回答 `q` 次询问,每次给出 `(x,k)`,输出从 `x` 跳跃 `k` 次后的位置编号。

试补全程序。

#include <iostream>
using namespace std;

const int N = 100010, LOG = 20;
int a[N], dp[N][LOG];

int main() {
    int n, q;
    cin >> n >> q;
    for (int i = 0; i < n; i++) cin >> a[i];
    for (int i = 0; i < n; i++) {
        dp[i][0] = /* ① */;
    }
    for (int k = 1; k < LOG; k++) {
        for (int i = 0; i < n; i++) {
            dp[i][k] = /* ② */;
        }
    }

    while (q--) {
        int x, k;
        cin >> x >> k;
        int u = x;
        for (int j = 0; j < LOG; j++) {
            if (/* ③ */) {
                u = /* ④ */;
            }
        }
        cout << /* ⑤ */ << endl;
    }
    return 0;
}

38 题(单选题3 分)

① 处应填( )。

A.
i
B.
a[i]
C.
0
D.
dp[i][1]

正确答案B

解析详情

【答案】B

【考点】倍增初始化

【解析】 `dp[i][0]` 表示从位置 `i` 跳 20=12^0=1 次后的编号,按定义就是 `a[i]`。

【易错点】 `dp[i][0]` 不是原地不动状态。

39 题(单选题3 分)

② 处应填( )。

A.
dp[dp[i][k - 1]][k - 1]
B.
dp[i][k - 1] + dp[i][k - 1]
C.
dp[i - 1][k - 1]
D.
dp[k - 1][i]

正确答案A

解析详情

【答案】A

【考点】倍增转移

【解析】 跳 2k2^k 次可拆成两段 2k12^{k-1} 次,先到 `dp[i][k-1]`,再跳同样次数,因此转移为 `dp[dp[i][k-1]][k-1]`。

【易错点】 两段跳跃要做函数复合,不能把位置编号相加。

40 题(单选题3 分)

③ 处应填( )。

A.
k & j
B.
k >> j
C.
(k >> j) & 1
D.
(k >> j) ^ 1

正确答案C

解析详情

【答案】C

【考点】二进制拆分

【解析】 枚举第 `j` 位时,只有 `k` 的该位为 1 才执行对应的 2j2^j 次跳跃,条件应为 `(k >> j) & 1`。

【易错点】 `k >> j` 可能大于 1,显式取最低位才能得到当前比特。

41 题(单选题3 分)

④ 处应填( )。

A.
dp[j][u]
B.
dp[k][u]
C.
dp[u][j]
D.
a[u]

正确答案C

解析详情

【答案】C

【考点】倍增查询

【解析】 当第 `j` 位有效时,当前位置 `u` 应沿预处理表跳 2j2^j 次,更新为 `dp[u][j]`。

【易错点】 倍增表第一维是当前位置,第二维是二进制位。

42 题(单选题3 分)

⑤ 处应填( )。

A.
u
B.
x
C.
k
D.
dp[u][0]

正确答案A

解析详情

【答案】A

【考点】查询结果

【解析】 循环结束后 `u` 已经累计完成 `k` 次跳跃,应该直接输出 `u`。

【易错点】 再输出 `dp[u][0]` 会额外多跳一次。