【题解】2023 NOI 春季测试 3 of 4

本文最后更新于:2025年2月18日 凌晨

A. 涂色游戏

Problem

题意:\(n\times m\) 的网格,\(q\) 次询问,每次涂一行或一列,新颜色会覆盖旧颜色,输出最终形态。

\(1\le \sum nm\)\(\sum q\le 10^6\)

考虑倒序执行这 \(q\) 个操作。

对每一行和每一列用 std::unordered_map 存当前还有哪一些方格未被涂色。

因为反着执行涂色时旧颜色一定不会被覆盖,故对于一个操作遍历该行/列对应的容器,未涂色的涂色,再将该方格编号从容器中删掉即可。

时间复杂度 \(O(mn)\)

std::unordered_map 插值和删值的均摊时间复杂度是 \(O(1)\) 的。

B. 幂次

Problem

题意:给定正整数 \(n,k\),求 \(1\sim n\) 中有多少正整数 \(x\) 可以表示为 \(x=a^b\) 的形式,其中 \(a,b\in \mathbb N^+\)\(b\ge k\)

\(1\le n \le 10^{18}\)\(1\le k \le 100\)

按照 \(k\) 范围分治。

首先,当 \(k=1\) 时,\(ans=n\)。因为所有 \(x\) 都能表示为 \(x^1\)

其次,当 \(k\ge 3\) 时,可以暴力枚举底数 \(a\),因为 \((10^6)^3=10^{18}\),底数十分有限。

最后,\(k=2\) 时,一个结论是小于等于 \(x\) 的完全平方数有 \(sqrt(x)\) 个,但其中有一些和指数大于 \(2\) 时的计算结果重复,考虑容斥。在统计 \(k\ge 3\) 的过程中顺便记录哪些计入答案的数属于完全平方数,令 \(k\ge 3\) 时的答案为 \(cnt\),有 \(num\) 个完全平方数,则 \(ans=cnt+sqrt(x)-num\)

容易爆 long long ,可以开 __int128

小心精度问题,用 std::sqrtl() 而不是 std::sqrt()

C. 圣诞树

Problem

好题

题意:给定二维坐标系上 \(n\) 个点构成的凸多边形,求从 \(y\) 轴最高点出发的一条最短路径,要求经过 \(n\) 个点且每个点仅能经过一次,依次输出编号。

\(3\le n\le 1000\)\(|x_i|,|y_i|\le 10^7\)

正解是区间dp,不是很会。

只会 \(3\le n\le18\),不过加上两个特殊性质一共能拿到 80pts。

套路题,最短哈密顿路径,考虑状压dp。

令起点为 \(s\),则 \(dp[i][j]\) 代表从 \(s\)\(j\) ,且经过 \(i\) 的二进制为 \(1\) 的位数对应编号的点的最短路径长度。

\(dp[i][j]=\mathop\min\limits_{k\in[1,n]}(dp[i\oplus2^j][k]+dis[k][j])\)

答案为 \(\min\limits_{i\in[1,n]}(dp[2^n-1][i])\)

接下来考虑如何记录路径。

\(pre[mask][j]=k\) 表示状态为 \(mask\),当前点 \(j\) 从点 \(k\) 转移过来最优。

状态转移时 \(pre\)\(dp\) 同步。

统计答案时,\(mask\) 对应为 \(1\) 的位异或变成 \(0\),即可回溯到上一状态。


【题解】2023 NOI 春季测试 3 of 4
https://kisuraop.github.io/posts/a073199c.html
作者
KisuraOP
发布于
2023年10月2日
许可协议