2022 年床上碰系列题解

CSP-S 2022

A. 假期计划

注意到链 1abcd1 的长度比较小,那么可以考虑折半做 .

枚举二元组 (b,c),那么问题变为对于点 u1vu 的最大分数,这个可以平凡预处理 .

不过链 1abcd1 中可能出现答案与 b,c 或另一条链上的答案相同的情况,改成记前三大值就可以了 .

好像不太能叫 meet-in-the-middle,时间复杂度 Θ(n(n+m)) .

B. 策略游戏

答案的贡献肯定在 {a},{b} 中的最大 / 最小非负数和最大 / 最小负数处取到,于是八个 ST 表分类讨论即可 . 精细一点可以做到四个 ST 表 .

时间复杂度 Θ(nlogn+q) .

C. 星战

根据一些阅读可以知道问题就是判断出度都为 1,不过这个修改的形式是对入度比较友好,令 I(u)={vvu} 也就是 u 的所有入边,这里的集合是多重集,那么可以改成判断 u=1nI(u)=[1:n] .

那么可以想维护全局集合并的 Hash,只有 1, 3 操作有用,形式就是加一个元素或者删一个元素 . 那么这个 Hash 只需要能加 / 删元素就行 .

这种 Hash 还是比较多的,比较常见的随机点权后 Sum Hash, XOR Hashing 啥的都是可以支持 .

我感觉这个 motivation 是比较自然的,别的题解的有点诡异了 . 时间复杂度 Θ(n+m+q) .

D. 数据传输

k2 平凡,关注一下 k=3 的情况 .

因为所有 v 都是正的所以可以观察发现对于询问 (u,v) 最优方案肯定是走在 uv 的毛毛虫上 . 那么不难想到的 DP 是 dpu,0/1 表示目前在 u 或者 u 的儿子时的答案 .

不过最后肯定是要动态 DP 优化,这种状态的转移写出来是 5×5(min,+) 矩阵乘法形式,是过不去的 .

重新审视这个 DP,可以发现实际上转移所需的信息只有「距离 u 点为 k 的所有点答案的最小值」,那么可以改写状态为 dpu,k 为距离 u 点为 k 的点答案的最小值(k=0,1,2),那么可以得到转移:

dpu,0=min{dpu,0,dpu,1,dpu,2}+vudpu,1=min{dpu,0,dpu,0+wu,min{dpu,0+dpu,1}+wu}dpu,2=dpu,1

其中 u 表示链上 u 的前驱结点,wu 表示 u 所有邻接点权值的最小值 .

更精细地操作,可以写成 (min,+) 矩阵乘法的形式:

[vivivi0wi0][dpu,0dpu,1dpu,2]=[dpu,0dpu,1dpu,2]

那么倍增处理即可做到 Θ(k3(n+q)logn) .

好像有做法是 Θ(k3(n+qlog2+q/nn)) 的,有个题解那个线性的上界应该不对,zzq's blog .

NOIP 2022

A. 种花

不会 .

B. 喵了个喵

喵 .

首先一些基本策略是预留一个空栈 S 辅助,那么对于一个栈 S

  • 如果牌堆顶端元素 x 和栈顶元素种类相同,则可以让 x 入栈 S,即可消掉 S 的栈顶元素 .
  • 如果牌堆顶端元素 x 和栈底元素种类相同,则可以让 x 入栈 S,使用操作 2 即可消掉 S 的栈底元素 .

这样就可以消掉某个栈的栈顶或栈底了,不过根据这个策略对于中间的元素是不容易处理的,因为本题 k<2n,所以可以想到尽量控制每个栈元素不要超过两个 .

首先看 k=2n2 的部分,其实非常平凡,能消就消,否则扔到随便一个大小不超过 1 的非空栈里即可 .

然后只需要处理 k=2n1 的情况,多了一个种类 x,只需要考虑上面的策略无法执行的情况 . 可以考虑 x 之后的栈底元素和自身的位置,具体策略如下:

  • 首先如果下一个自己先于所有栈底元素出现,那么把 x 入空栈 S,则后面的栈顶元素不需要用到 S 消,出现自己的时候即可清空栈 S .
  • 否则找到最近一个栈底元素的位置 pB .
    • 如果 pB 对应栈 S 的栈顶牌种类在排堆 xpB 位置共出现了偶数次,则中间所有的栈顶牌都可以直接消掉,那么把 x 放到 pB 同类元素所在栈 SpB 放到空栈 S 里,然后用操作 2 即可消掉 S 的栈底 .
    • 如果 pB 对应栈 S 的栈顶牌种类在排堆 xpB 位置共出现了奇数次,则用 S 的栈顶牌消掉 pB,让 x 入空栈 SpB 入栈 S,之后 S 会被天然清空,此时令 S 成为新的空栈,即 SS 即可 .

模拟上述过程,时间复杂度单次 Θ(m),不过最朴素的暴力 Θ(nm) 模拟也可以过 .

Code .

C. 建造军营

首先缩边双变成树上问题,令点 u 所表示的边双大小为 eV(u),边数为 eE(u) .

那么可以发现对于选中点集 S,边集必然是 S 内两两简单路径并的超集,那么可以想到设计一个 01 背包转移,需要计算 S 内两两简单路径并的大小以便于计算答案 .

为了方便,令 w(u) 表示 u 子树内一个点都不选的答案,即 w(u)=vsubtree(u)2eE(v)+|son(v)|,可以朴素预处理 .

简单路径并可以按 LCA 的位置大致确定,于是令 dpu,d=0/1 表示 u 子树内选点集 S,其中 d=[LCA(S)=u] 的答案,那么就可以算了,具体转移如下,不再多做解释:

dpu,0=2eV(u)+eE(u)vson(u)(2w(v)+dpv,1)w(u)dpu,1=2eE(u)vson(u)(2dpv,2+dpv,1)2|son(u)|1vson(u)vvdpv,1

因为模数比较好所以 vson(u)vv 这个可以直接除掉 v 的贡献算,否则可以维护前后缀积 .

时间复杂度 Θ(n+m) .

D. 比赛

首先按右端点排序后扫描线,动态维护一个单调栈,那么就变成了:

维护序列 {xn},{yn},支持:

  • 对于序列 {x}{y} 的区间赋值 .
  • 查询区间历史 xy 和 .

使用线段树维护,对于每个节点,维护 s,sx,sy,sxy 表示区间历史 xy 和,区间 x,y,xy 和(维护 x,y 和方便复合标记).

考虑维护标记六元组 (ax,ay,axy,ac,cx,cy),其中 cx,cy 是区间覆盖标记,a 标记表示真正的历史 xys 做了变换 s=s+axsx+aysy+axysxy+aclen .

那么信息、标记的合并以及信息对标记的复合都可以通过一些讨论得出,总时间复杂度为 Θ(nlogn) .

附:可以使用线段树的双半群模型分析,便于得到结果,Link .

NOIST 2022

A. 涂色游戏

不会 .

B. 幂次

首先特判 k=1,令 f(n) 表示 [1,n] 能表示为 x=ab 形式的整数 x 个数,其中 a1,b2,那么答案可以简单表述为:

ans=f(n)i=2k1f(ni)

考虑对指数容斥,观察可以发现 f(n)=1i2μ(i)(ni1) .

那么直接算就可以,时间复杂度 Θ(klogn) . 稍卡精度 .

C. 圣诞树

Key Observation 答案路径一定不会有两条线段相交 .

证明平凡 .

那么可以直接导出对于区间 [l,r],其决策点必然位于 l1r+1,区间 DP 即可 . 时间复杂度 Θ(n2) .

D. 密码锁

k2 平凡略过 . 考虑 k>2 情况 .

对于 k=3,考虑二分答案 x,然后类似 k=2,全局最大值和全局最小值必然不在同一行,于是 Θ(k) 枚举最小值的位置后假设最小值为 m,剩下的那一行为 {an},则只需要满足限制 aixmai 即可 . 那么就相当于若干组区间并后判断是否交 .

可以改成若干区间 +1,最后看有没有位置被加了 n 次,那么差分即可 .

k=4 是几乎一致的,只需要把区间改成矩形,扫描线维护即可 .

时间复杂度好像是单次 Θ(nk2log2v),其中 v 是值域 . 没写 .

wxy:直接在一个维度上双指针,另一个维度上维护 [x,x+k] 内的颜色数,这样每种颜色 set 维护下前驱就行了。

我暂且蒙在鼓里。好像很强阿!

posted @   yspm  阅读(326)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
历史上的今天:
2020-05-13 题解【洛谷 P1466 [USACO2.2]集合 Subset Sums】
😅​
点击右上角即可分享
微信分享提示