[杂谈] 日报 D1
因为又停课了所以可以开始写日报了 .
打算让格式彻底崩坏掉 , 可读性什么的无所谓了 , 权当整理下一天的零碎内容 , 写一堆没用的 , 以及调整下心情 .
不想写太多负面情绪 , 不过还是好烦躁 , 难受死了 .
每做题 2 个小时就得睡 20 分钟又是什么毛病啊 .
于是去小卖部进了一堆零食 , 大概是对抗低血糖 ? 不过感觉不太是血糖的事情 , 估计是有点东西嚼嚼嚼嚼嚼能维持注意力 .
应该不算嗜睡症吧 , 毕竟我还没到走走路原地开睡的地步 .
苍穹计划 D21 T1
这个真没得喷 , 真绝世好题 .
连场上带赛后改加起来 8h 拿下了 . 也算是自己拿下的吧 ( 叹气 ) .
从 \(O(nm^4)\) 爆砍复杂度到 \(O(nm)\) 看起来很强力 , 实际上也很强力 .
首先这个 dp 设计的过程中就时刻注意一种 , 一直用贪心的思想限制可能状态 , 从而减少状态量的一个 idea .
这个边经过次数限制很难受 ,基本上排除了通过 dp 每条边走几次之外的做法 . 子树输入/输出流数量两位状态必须维护 , 暴力转移时 \(O(nm^5)\) 的 , 通过讨论子树形态就能得出要贪心在子树内用掉尽可能多的输出流 . 另外还要观察到这个尽可能多的输出流是两棵子树的输入流 , 以及输出流之和三者的 min . 然后优化转移 , 变成 \(O(nm^4)\) .
然后有意思的就来了 , 根据这个贪心转移 , 只有输入流为子树 max , 以及输出流为 0 这两种情况才存在有意义的量 .
所以可以直接把状态变成一维 , 两个子树合并 , 各有两种情况的 dp 数组 , 分别对应合并即可 . 因为 dp 数组大小不限制 , 所以没有树上背包均摊 , 复杂度 \(O(nm^2)\) .
然后更有意思的来了 , 这里的 dp 数组显然是一个凸包 , 虽然这不能用来 wqs 二分 , 但是到了这一步 , 发现四种转移全是凸包求和形式的 , 直接用闵和优化做到 \(O(m)\) 合并 , 总复杂度 \(O(nm)\) .
这个题里装了一个贪心相关的状态设计优化 , 还有关于优良的凸性质的运用 .
关于凸性 , 显然只求单点时用 wqs 二分 , 不过并行性问题同样有运用的方法 , 不要忘记闵和等可以优化凸包的合并 , 得到更优的复杂度 .
最有意思的还是先设计出一个巨大状态 , 然后在不改变状态设计意义的情况下 , 能找到基于贪心的优秀的转移 , 以及这种贪心转移造成的状态量大缩水 . 在这种题设有很多可以贪心考虑的性质时 , 这个跃进式的复杂度减少其实还是挺自然的 .
至于凸优化反而只是临门一脚了 .
[COTS 2025] Hijerarhija
这东西第一反应树背包 , 然后发现没均摊 .
冷静下来想想 , 为什么要树背包 , 本质上是因为在树上加了限制 , 使得不得不通过合并子树幂级数来处理 .
以及为什么树背包天然 \(n^3\) 而线性背包天然 \(n^2\) , 是因为线性背包始终是 \(O(1)\) 位的幂级数卷进 \(O(n)\) 的 , 而树背包为了维持子树合并结构 , 不得不卷积两个 \(O(n)\) 的幂级数 .
回到这道题 , 这道题很好地把树上限制和背包 (最优化 ) 卷积的关系清晰化了 , 而不是庸俗的想到树 dp 就是子树合并或者链预处理之类的 . 本质上是依据树上的限制来安排我们 dp 的顺序 .
想清楚这一点 , 这道题就很好分析了 , 发现这里的限制是插入一个位置 , 一定要让其祖先链都至少插入 \(1\) . 这里显然子树合并是走不通的 , 但是发现直要能让 \(u\) 依赖一个祖先都插入的基础上 dp , 就是正确的 . 这提示我们在以 dfs 序为限制的顺序 .
因此 , 可以直接 dfs , 每次到 \(u\) 时让 dp 数组处于祖先链都插入了树的情况 , 这时 \(u\) 要么整个子树都不插入 , 那相当于没有更新 , 把当前的 dp 数组备份一下 , 否则自己先强制插入 \(1\) , 同时尝试插入 \(c_u\) , 传给子树时 dp 数组仍然满足需求 . 返回时和备份数组取一次 max , 就取消了整个子树的强制选择 , 并且考虑到的子树的所有情况 .
其实个人认为这道题不是一道所谓的 tricky 题目 , 相反 , 如果能思考本质 , 可能更容易解决 . 发现树 dp 本质是为了容易满足树上限制而重新安排的 dp 顺序 , 就容易发现 dfs 序上可以做到 \(O(1)\) 位幂级数插入 , 从而降低复杂度 .
同样的道理在 NOI2024 D2T2 中也适用 , 是为了树上限制而根据树重新安排了 dp 顺序 , 明确这一点会使得设计 dp 变得更容易一些 .
[COTS 2025] Promet
一道很需要思维灵活性的计数题 .
首先单独考虑所有 \(n\) 个都满足条件 , 发现这等价于全图唯一无入度点是 \(1\) , 无出度点是 \(n\) , 也就是要安排前 \(n-1\) 个点既有出度又有入度 ( \(1\) 除外 ) , 这样也保证了 \(n\) 有入度 .
直接 dp 是 \(O(n^3)\) 的 , 考虑其实我们要的就是 \(n-1\) 个点中无出度点恰好 \(0\) 个 , 考虑容斥 , 钦定前 \(n-1\) 个中有 \(j\) 个无出度 , 那么每次新插入一个点的入度就从所有钦定之外的点中任意找 . 这样就可以做到对 \(1\cdots n\) 都预处理出 \(i\) 个都满足条件的 \(s_i\) .
然后考虑对于有 \(i\) 个点满足条件的情况 , 这 \(i\) 个点之间的连边情况数就是 \(s_i\) , 现在考虑将不满足的插入进去 . 发现不满足的也要分两种 , 一种是有来自 \(1\) 路径的 , 一种是没有的 . 直接 dp 是 \(O(n^3)\) .
为了节约复杂度 , 发现没有连 \(1\) 的点连另外两种点时 , 只连所有后缀的点 , 也就是说这种点眼里另外两种点本质相同 . 所以先用满足条件的和连 \(1\) 的点处理出 \(g_{i,j}\) 表示长度为 \(i\) , 有 \(j\) 个满足条件的点的方案数 , 复杂度 \(O(n^2)\) .
最后再把没连 \(1\) 的插入进去 , 也是 \(O(n^2)\) 的 .
这道题设计出了这样一个特殊的序列 , 使得这个序列可以通过拆分不同种类的点 , 把插入点分若干步进行 , 且每一步之间的连边不互相影响 , 从而降低了处理整个序列的复杂度 . 关键是题意还很自然 , 划分点是根据 dp 需求而形成的 .

浙公网安备 33010602011771号