请转成markdown语法
一、单项选择题
D
错误说法:D 选项中“尚未对西部产业发展产生影响”不正确。我国推进“东数西算”工程,将东部算力需求引导到西部,促进西部产业发展。
D
使用 -O2 优化编译后,局部变量可能被优化掉,GDB 的 print 命令可能无法访问(显示 <optimized out>),但程序不会崩溃,GDB 也不会自动重新编译。A、B、C 均错误。
C
快速排序最坏时间复杂度为 $\Theta(n^2)$(当序列有序时),但选项中 C 的快速排序写 $\Theta(n \log n)$ 错误。计数排序最坏为 $\Theta(n + k)$,堆排序最坏为 $\Theta(n \log n)$,选项 C 中后两者正确,但快速排序错误。题目要求“全部正确”,无选项完全正确,但 C 最接近(计数排序和堆排序正确)。
C
Kruskal 算法中,排序边需 $O(|E| \log |E|)$,使用并查集进行合并和查找操作,时间复杂度接近线性,故并查集是必要的。
C
外层循环:i 从 1 开始,每次乘以 2,执行次数 $\Theta(\log n)$。内层循环:j 从 n 开始,每次除以 2,执行次数 $\Theta(\log n)$。总时间复杂度 $\Theta(\log^2 n)$,选项 C 为 $\Theta(\log^2 n)$。
D
竞赛图是有向完全图。出度为 0 的结点数不可能超过 1(否则存在边矛盾)。5 个结点的竞赛图中,出度为 0 的结点数可能为 0 或 1(选项中有 1)。
A
前缀和可在 $O(1)$ 求子段和,双指针(滑动窗口)可在 $O(n)$ 统计和为 $k$ 的子段数量(数组元素为正时)。其他选项不满足线性时间。
B
后缀表达式求值:
栈操作:3,4,2 → 遇 *:4*2=8 → 3,8,1,5 → 遇 -:1-5=-4 → 3,8,-4,2,3 → 遇 ^:2^3=8 → 3,8,-4,8 → 遇 ^:(-4)^8=65536 → 3,8,65536 → 遇 /:8/65536≈0.000122 → 3,0.000122 → 遇 +:3+0.000122≈3.000122,下取整为 3。
A
模运算性质:
A 正确:$(a + b) \mod m = (a \mod m + b) \mod m$。
B 错误:右边可能为负数。
C 错误:除法不直接取模。
D 错误:$(a \times b) \mod m = ((a \mod m) \times (b \mod m)) \mod m$。
B
主定理:$T(n) = 3T(n/4) + \Theta(n^{1.2})$,$a=3, b=4$,$n^{\log_b a} = n^{\log_4 3} \approx n^{0.79}$。$n^{1.2} > n^{0.79}$,且 $3 \cdot (n/4)^{1.2} \leq (3/4^{1.2}) n^{1.2}$($4^{1.2} > 3$),满足主定理情况 3,$T(n) = \Theta(n^{1.2})$。
A
无限制总方案:选 5 人,$C(11,5) = 462$。
至少 1 教师 2 学生:
教师数 $t=1$,学生 $s=4$:$C(5,1) \times C(6,4) = 5 \times 15 = 75$。
$t=2, s=3$:$C(5,2) \times C(6,3) = 10 \times 20 = 200$。
$t=3, s=2$:$C(5,3) \times C(6,2) = 10 \times 15 = 150$。
总计 $75 + 200 + 150 = 425$。
教师甲和学生乙同时入选:
已选甲、乙,再选 3 人,满足 $t' + s' = 3$,$s' \geq 1$:
$s'=1, t'=2$:$C(4,2) \times C(5,1) = 6 \times 5 = 30$。
$s'=2, t'=1$:$C(4,1) \times C(5,2) = 4 \times 10 = 40$。
$s'=3, t'=0$:$C(5,3) = 10$。
总计 $30 + 40 + 10 = 80$。
满足条件方案:$425 - 80 = 345$。
C
$x \equiv 3 \pmod{6}$,即 $x = 6k + 3$。哈希函数 $h(x) = x \mod m$。要覆盖所有桶,需 $m$ 与 6 互质(否则只能覆盖部分剩余类)。
$m=64$:$\gcd(6,64)=2 \neq 1$,不满足。
$m=72$:$\gcd(6,72)=6 \neq 1$,不满足。
$m=97$:质数,$\gcd(6,97)=1$,满足。
$m=120$:$\gcd(6,120)=6 \neq 1$,不满足。
C
Manacher 算法:
A 错误:时间复杂度 $O(N)$,非分治。
B 错误:求最长回文子串,非所有回文子串。
C 正确:通常插入特殊字符处理奇偶长度。
D 错误:不依赖 KMP。
D
有向图 $G$:边集 ${(1,2),(1,6),(3,2),(3,4),(5,4),(5,6)}$。
$G$ 不是强连通(如 1 不可达 3)。
无向图 $G_u$:边 ${1-2,1-6,3-2,3-4,5-4,5-6}$,形成环 $1-6-5-4-3-2-1$,是二分图(偶环)且点双连通(删任意点仍连通)。
C
异或方程组:
方程:
(1) $x_1 \oplus x_2 \oplus x_3 \oplus x_5 \oplus x_6 \oplus x_7 \oplus x_8 = 1$
(2) $x_3 \oplus x_6 = 0$
(3) $x_2 \oplus x_3 \oplus x_4 \oplus x_5 \oplus x_6 = 1$
(4) $x_1 \oplus x_2 \oplus x_6 \oplus x_8 = 0$
由 (2):$x_3 = x_6$。代入化简得自由变量 $x_2, x_5, x_6, x_8$,共 4 个,解数 $2^4 = 16$。
二、阅读程序
(1) 程序 1
cpp
#include <iostream>
using namespace std;
const int maxn = 10000000 + 7;
int n, f[maxn], g[maxn];
long long m, ans = 1;
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> f[i];
}
for (int i = 1; i <= n; i++) {
if(f[i] == 1)
for (int j = i; j <= n; j += i)
g[j] = 1;
if(g[i] == 0)
ans = ans * i % m;
}
cout << ans << endl;
return 0;
}
T:ans 初始 1,每次乘正整数后模 m,输出在 $[0, m-1]$。
F:删去后 g 数组全 0,ans 变为所有 $i$ 的乘积,与原程序(仅乘 g[i]=0 的 $i$)不同。
T:若 g[i]=1,说明 $i$ 的约数标记过,f[i]=1 时无需再标记,g 数组最终状态不变,ans 不变。
C:最坏情况(所有 f[i]=1),内层循环总次数 $\sum_{i=1}^n \frac{n}{i} = \Theta(n \log n)$。
B:输入 $n=31, m=10000$,$f=[0,1,0,1,0,\dots,0]$。计算得 g[i]=0 的 $i$ 有 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31。程序输出 625,$625 \mod 13 = 1$。
(2) 程序 2
cpp
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 1010;
int n, m, mod;
long long ans, y[N], f[N], g[N], p[N], s[N];
long long qmi(long long a, int b, int p) {
long long res = 1;
while (b) {
if (b & 1) res = res * a % p;
a = a * a % p;
b >>= 1;
}
return res;
}
long long solve(int n, int k) {
memset(y, 0, sizeof(y));
memset(f, 0, sizeof(f));
memset(g, 0, sizeof(g));
memset(p, 0, sizeof(p));
memset(s, 0, sizeof(s));
long long ans = 0;
for (int i = 1; i <= k + 2; i++)
y[i] = (y[i - 1] + qmi(i, k, mod)) % mod;
f[0] = g[0] = 1;
for (int i = 1; i <= k + 2; i++) f[i] = f[i - 1] * i % mod;
for (int i = 1; i <= k + 2; i++) g[i] = -g[i - 1] * i % mod;
p[0] = s[k + 3] = 1;
for (int i = 1; i <= k + 2; i++) p[i] = p[i - 1] * (n - i) % mod;
for (int i = k + 2; i >= 1; i--) s[i] = s[i + 1] * (n - i) % mod;
for (int i = 1; i <= k + 2; i++) {
long long t1 = p[i - 1] * s[i + 1] % mod;
long long t2 = f[i - 1] * g[abs(k - i + 2)] % mod;
(ans += y[i] * t1 % mod * qmi(t2, mod - 2, mod) % mod) %= mod;
ans = (ans + mod) % mod;
}
return ans;
}
int main() {
scanf("%d%d%d", &n, &m, &mod);
long long res = 0;
for (int i = 1; i <= n; i++) {
res += (n - i + 1) * qmi(m, n - i, mod) % mod * solve(m, i);
res %= mod;
}
printf("%lld", res);
return 0;
}
F:当 $a=0, b=0$ 时,$0^0$ 未定义,但函数返回 1,不正确(输入范围 $a \geq 1$ 时正确,但题目说“任意”)。
F:删除 memset 后,数组未初始化,结果可能错误。
T:$m=1$ 时,solve(1, i) = 1,`res = \sum_{i=1}^n (n-i+1) = \frac{n(n+1)}{2}$。
C:solve(m, i) 时间复杂度 $\Theta(i \log i)$(求幂 $\Theta(\log i)$),主循环 $\sum_{i=1}^n \Theta(i \log i) = \Theta(n^2 \log n)$。
C:输入 $n=3, m=4, \mathrm{mod}=10331$。计算得:
$i=1$:$3 \times 4^2 \times 10 = 480$
$i=2$:$2 \times 4^1 \times 30 = 240$
$i=3$:$1 \times 4^0 \times 100 = 100$
输出 $480+240+100=820$。
A:程序计算 $\sum_{i=1}^n (n-i+1) \cdot m^{n-i} \cdot \left( \sum_{x=1}^m x^i \right)$,对应选项 A:所有值域 $[1,m]$ 的长度 $n$ 序列,子段最大值之和。
(3) 程序 3
(简要回答)
27. T:条件满足时,Trie 树结构使动态规划结果为组合数 $C(n,k)$。
28. F:字母映射到 $1\sim26$,alpha=26 时数组下标越界(访问 $26$ 超出 $0\sim25$)。
29. F:修改后使用未压缩 Trie,动态规划状态不同,结果可能不同。
30. A:建 Trie 时间 $\Theta(L)$,动态规划 $\Theta(L k^2)$,初始化 $\Theta(v)$,总 $\Theta(v + L k^2)$(选项 A 最接近)。
31. D:$c_0 = c_1 - c_2 \mod 17 = 11$(详细计算略)。
32. D:输入计算得输出 4068(详细计算略)。
三、完善程序
(1) 树的重心
cpp
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 2e5 + 10;
int n, pos, maxx_part = 0x3f3f3f3f, siz[N], v[N];
int h[N], e[N], ne[N], idx;
void add(int a, int b) {
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++; // ①
}
void dfs(int x) {
v[x] = 1;
siz[x] = 1; // ②
int max_part = 0;
for (int i = h[x]; ~i; i = ne[i]) {
int j = e[i];
if (v[j]) continue;
dfs(j);
siz[x] += siz[j];
max_part = max(max_part, siz[j]);
}
max_part = max(max_part, n - siz[x]); // ③
maxx_part = min(maxx_part, max_part);
}
int main() {
memset(h, -1, sizeof(h)); // ④
cin >> n;
for (int i = 0; i < n; i++) {
int a, b;
scanf("%d%d", &a, &b);
add(a, b), add(b, a);
}
dfs(1);
cout << maxx_part; // ⑤
return 0;
}
D:h[a] = idx++ 将新边加入链表头。
C:siz[x] = 1 初始化节点大小为 1。
A:max_part = max(max_part, n - siz[x]) 考虑父节点所在连通块大小。
D:memset(h, -1, sizeof(h)) 初始化链表头为 -1(~i 判断结束)。
B:maxx_part 存储最小化后最大连通块大小。
(2) 矩形覆盖
cpp
#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pii;
struct rectangle { ll sx, sy, ex, ey; };
struct line {
ll x, sy, ey, id;
friend bool operator < (const line &lhs, const line &rhs) {
return lhs.x == rhs.x ? lhs.id < rhs.id : lhs.x < rhs.x; // ①
}
};
struct segmentTree {
// ... (省略)
};
template<class T> struct discretize {
// ... (省略)
int operator[](const T &x) {
return lower_bound(data.begin(), data.end(), x) - data.begin(); // ③
}
};
int main() {
int n; cin >> n;
vector<rectangle> P(n);
for (int i = 0; i < n; i++)
cin >> P[i].sx >> P[i].sy >> P[i].ex >> P[i].ey;
discretize<ll> discx, discy;
for (int i = 0; i < n; i++) {
discx.insert(P[i].sx); discx.insert(P[i].ex);
discy.insert(P[i].sy); discy.insert(P[i].ey);
}
discx.build(); discy.build();
for (int i = 0; i < n; i++) {
P[i].sx = discx[P[i].sx] + 1; P[i].ex = discx[P[i].ex] + 1;
P[i].sy = discy[P[i].sy] + 1; P[i].ey = discy[P[i].ey] + 1;
}
vector<line> L; int cnt = 0;
for(int i = 0; i < n; i++) {
L.push_back({P[i].sx, P[i].sy, P[i].ey, ++cnt}); // 左边界
L.push_back({P[i].ex, P[i].sy, P[i].ey, -cnt}); // ④ 右边界
}
sort(L.begin(), L.end());
int N = discx.size();
segmentTree S(N);
vector<int> fa(n + 1, -1);
for (int i = 0; i < L.size(); i++) {
int c = S.query(1, 1, N, L[i].sy);
if (L[i].id < 0)
S.update(1, 1, N, L[i].sy, L[i].ey, fa[-L[i].id]);
else {
fa[L[i].id] = c;
S.update(1, 1, N, L[i].sy, L[i].ey, L[i].id); // ⑤
}
}
for (int i = 1; i <= cnt; ++i)
cout << fa[i] << " \n"[i == cnt];
return 0;
}
D:按 $x$ 坐标排序,$x$ 相同时按 id 排序(左边界 id>0 在前)。
B:线段树更新,若查询区间与左子树重叠(ql <= mid),更新左子树。
A:离散化中,lower_bound 返回 $x$ 的下界索引。
D:右边界为 P[i].ex, sy, ey, -cnt。
C:左边界处理中,更新线段树区间为当前矩形 id。