2022 年床上碰系列题解
CSP-S 2022
A. 假期计划
注意到链 \(1\!-\!a\!-\!b\!-\!c\!-\!d\!-\!1\) 的长度比较小,那么可以考虑折半做 .
枚举二元组 \((b,c)\),那么问题变为对于点 \(u\) 问 \(1\!-\!v\!-\!u\) 的最大分数,这个可以平凡预处理 .
不过链 \(1\!-\!a\!-\!b\) 和 \(c\!-\!d\!-\!1\) 中可能出现答案与 \(b,c\) 或另一条链上的答案相同的情况,改成记前三大值就可以了 .
好像不太能叫 meet-in-the-middle,时间复杂度 \(\Theta(n(n+m))\) .
B. 策略游戏
答案的贡献肯定在 \(\{a\},\{b\}\) 中的最大 / 最小非负数和最大 / 最小负数处取到,于是八个 ST 表分类讨论即可 . 精细一点可以做到四个 ST 表 .
时间复杂度 \(\Theta(n\log n+q)\) .
C. 星战
根据一些阅读可以知道问题就是判断出度都为 \(1\),不过这个修改的形式是对入度比较友好,令 \(\mathcal I(u)=\{v\mid v\to u\}\) 也就是 \(u\) 的所有入边,这里的集合是多重集,那么可以改成判断 \(\displaystyle\bigcup_{u=1}^n\mathcal I(u)=[1:n]\) .
那么可以想维护全局集合并的 Hash,只有 1, 3 操作有用,形式就是加一个元素或者删一个元素 . 那么这个 Hash 只需要能加 / 删元素就行 .
这种 Hash 还是比较多的,比较常见的随机点权后 Sum Hash, XOR Hashing 啥的都是可以支持 .
我感觉这个 motivation 是比较自然的,别的题解的有点诡异了 . 时间复杂度 \(\Theta(n+m+q)\) .
D. 数据传输
\(k\le 2\) 平凡,关注一下 \(k=3\) 的情况 .
因为所有 \(v\) 都是正的所以可以观察发现对于询问 \((u,v)\) 最优方案肯定是走在 \(u\) 到 \(v\) 的毛毛虫上 . 那么不难想到的 DP 是 \(dp_{u,0/1}\) 表示目前在 \(u\) 或者 \(u\) 的儿子时的答案 .
不过最后肯定是要动态 DP 优化,这种状态的转移写出来是 \(5\times 5\) 的 \((\min,+)\) 矩阵乘法形式,是过不去的 .
重新审视这个 DP,可以发现实际上转移所需的信息只有「距离 \(u\) 点为 \(k\) 的所有点答案的最小值」,那么可以改写状态为 \(dp_{u,k}\) 为距离 \(u\) 点为 \(k\) 的点答案的最小值(\(k=0,1,2\)),那么可以得到转移:
其中 \(u'\) 表示链上 \(u\) 的前驱结点,\(w_u\) 表示 \(u\) 所有邻接点权值的最小值 .
更精细地操作,可以写成 \((\min,+)\) 矩阵乘法的形式:
那么倍增处理即可做到 \(\Theta(k^3(n+q)\log n)\) .
好像有做法是 \(\Theta(k^3(n+q\log_{2+q/n}n))\) 的,有个题解那个线性的上界应该不对,zzq's blog .
NOIP 2022
A. 种花
不会 .
B. 喵了个喵
喵 .
首先一些基本策略是预留一个空栈 \(S\) 辅助,那么对于一个栈 \(S'\):
- 如果牌堆顶端元素 \(x\) 和栈顶元素种类相同,则可以让 \(x\) 入栈 \(S'\),即可消掉 \(S'\) 的栈顶元素 .
- 如果牌堆顶端元素 \(x\) 和栈底元素种类相同,则可以让 \(x\) 入栈 \(S\),使用操作 2 即可消掉 \(S'\) 的栈底元素 .
这样就可以消掉某个栈的栈顶或栈底了,不过根据这个策略对于中间的元素是不容易处理的,因为本题 \(k<2n\),所以可以想到尽量控制每个栈元素不要超过两个 .
首先看 \(k=2n-2\) 的部分,其实非常平凡,能消就消,否则扔到随便一个大小不超过 1 的非空栈里即可 .
然后只需要处理 \(k=2n-1\) 的情况,多了一个种类 \(x\),只需要考虑上面的策略无法执行的情况 . 可以考虑 \(x\) 之后的栈底元素和自身的位置,具体策略如下:
- 首先如果下一个自己先于所有栈底元素出现,那么把 \(x\) 入空栈 \(S\),则后面的栈顶元素不需要用到 \(S\) 消,出现自己的时候即可清空栈 \(S\) .
- 否则找到最近一个栈底元素的位置 \(p_{\sf B}\) .
- 如果 \(p_{\sf B}\) 对应栈 \(S'\) 的栈顶牌种类在排堆 \(x\dots p_{\sf B}\) 位置共出现了偶数次,则中间所有的栈顶牌都可以直接消掉,那么把 \(x\) 放到 \(p_{\sf B}\) 同类元素所在栈 \(S'\),\(p_{\sf B}\) 放到空栈 \(S\) 里,然后用操作 2 即可消掉 \(S'\) 的栈底 .
- 如果 \(p_{\sf B}\) 对应栈 \(S'\) 的栈顶牌种类在排堆 \(x\dots p_{\sf B}\) 位置共出现了奇数次,则用 \(S'\) 的栈顶牌消掉 \(p_{\sf B}\),让 \(x\) 入空栈 \(S\),\(p_{\sf B}\) 入栈 \(S'\),之后 \(S'\) 会被天然清空,此时令 \(S'\) 成为新的空栈,即 \(S\gets S'\) 即可 .
模拟上述过程,时间复杂度单次 \(\Theta(m)\),不过最朴素的暴力 \(\Theta(nm)\) 模拟也可以过 .
Code .
C. 建造军营
首先缩边双变成树上问题,令点 \(u\) 所表示的边双大小为 \(e_{\sf V}(u)\),边数为 \(e_{\sf E}(u)\) .
那么可以发现对于选中点集 \(S\),边集必然是 \(S\) 内两两简单路径并的超集,那么可以想到设计一个 01 背包转移,需要计算 \(S\) 内两两简单路径并的大小以便于计算答案 .
为了方便,令 \(w(u)\) 表示 \(u\) 子树内一个点都不选的答案,即 \(\displaystyle w(u)=\prod_{v\in\operatorname{subtree}(u)}2^{e_{\sf E}(v)+|\operatorname{son}(v)|}\),可以朴素预处理 .
简单路径并可以按 LCA 的位置大致确定,于是令 \(dp_{u,d=0/1}\) 表示 \(u\) 子树内选点集 \(S\),其中 \(d=[\operatorname{LCA}(S)=u]\) 的答案,那么就可以算了,具体转移如下,不再多做解释:
因为模数比较好所以 \(v'\in\_\land v'\neq v\) 这个可以直接除掉 \(v\) 的贡献算,否则可以维护前后缀积 .
时间复杂度 \(\Theta(n+m)\) .
D. 比赛
首先按右端点排序后扫描线,动态维护一个单调栈,那么就变成了:
维护序列 \(\{x_n\},\{y_n\}\),支持:
- 对于序列 \(\{x\}\) 或 \(\{y\}\) 的区间赋值 .
- 查询区间历史 \(x\cdot y\) 和 .
使用线段树维护,对于每个节点,维护 \(s,s_{\sf x},s_{\sf y},s_{\sf xy}\) 表示区间历史 \(x\cdot y\) 和,区间 \(x,\,y,\,x\cdot y\) 和(维护 \(x,\,y\) 和方便复合标记).
考虑维护标记六元组 \((a_{\sf x},a_{\sf y},a_{\sf xy},a_{\sf c},c_{\sf x},c_{\sf y})\),其中 \(c_{\sf x},c_{\sf y}\) 是区间覆盖标记,\(a\) 标记表示真正的历史 \(x\cdot y\) 和 \(s'\) 做了变换 \(s'=s+a_{\sf x}s_{\sf x}+a_{\sf y}s_{\sf y}+a_{\sf xy}s_{\sf xy}+a_{\sf c}\cdot\mathrm{len}\) .
那么信息、标记的合并以及信息对标记的复合都可以通过一些讨论得出,总时间复杂度为 \(\Theta(n\log n)\) .
附:可以使用线段树的双半群模型分析,便于得到结果,Link .
NOIST 2022
A. 涂色游戏
不会 .
B. 幂次
首先特判 \(k=1\),令 \(f(n)\) 表示 \([1,n]\) 能表示为 \(x=a^b\) 形式的整数 \(x\) 个数,其中 \(a\ge 1,\,b\ge 2\),那么答案可以简单表述为:
考虑对指数容斥,观察可以发现 \(\displaystyle f(n)=1-\sum_{i\ge 2}\mu(i)(\lfloor\sqrt[i]{n}\rfloor-1)\) .
那么直接算就可以,时间复杂度 \(\Theta(k\log n)\) . 稍卡精度 .
C. 圣诞树
Key Observation \(\quad\) 答案路径一定不会有两条线段相交 .
证明平凡 .
那么可以直接导出对于区间 \([l,r]\),其决策点必然位于 \(l-1\) 或 \(r+1\),区间 DP 即可 . 时间复杂度 \(\Theta(n^2)\) .
D. 密码锁
\(k\le 2\) 平凡略过 . 考虑 \(k>2\) 情况 .
对于 \(k=3\),考虑二分答案 \(x\),然后类似 \(k=2\),全局最大值和全局最小值必然不在同一行,于是 \(\Theta(k)\) 枚举最小值的位置后假设最小值为 \(m\),剩下的那一行为 \(\{a_n\}\),则只需要满足限制 \(a_i-x\le m\le a_i\) 即可 . 那么就相当于若干组区间并后判断是否交 .
可以改成若干区间 +1,最后看有没有位置被加了 \(n\) 次,那么差分即可 .
\(k=4\) 是几乎一致的,只需要把区间改成矩形,扫描线维护即可 .
时间复杂度好像是单次 \(\Theta(nk^2\log^2v)\),其中 \(v\) 是值域 . 没写 .
wxy:直接在一个维度上双指针,另一个维度上维护 \([x,x+k]\) 内的颜色数,这样每种颜色 set
维护下前驱就行了。
我暂且蒙在鼓里。好像很强阿!
以下是博客签名,正文无关
本文来自博客园,作者:Jijidawang,转载请注明原文链接:https://www.cnblogs.com/CDOI-24374/p/17369518.html
版权声明:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0)进行许可。看完如果觉得有用请点个赞吧 QwQ