Live2D

Solution Set - “让季节停止哽咽”

0.「CTT 2017」「洛谷 P4004」Hello world!

  写答辩 听 Para 赞美最短解 冲到题解区看最短解 叉掉最短解并赞美作者 写答辩.

  这步长根号分治和修改次数均摊的味儿太明显了. 在步长大于 n 时, 一切操作都能暴力. 在步长小于 n 时, 我们需要快速找到路径上非 1a 值, 顺便维护同余步长的 a 和. 我们对步长 k<n 单独建一棵树, 每个点的新爹是原来的 k 级爹, 然后找非 1 可以直接 DSU, 维护和就在 DFN 序列上分块维护差分以平衡复杂度. 最后可以做到 O(nnloglogn+qn), 可能还要加个 DSU 的复杂度. (

1.「CTT 2017」「洛谷 P4006」小 Y 和二叉树

  答案序列的第一个点显然是度数 <3 的编号最小的点, 记为 r. 接下来考虑第二个点, 它可能是 r 右子树内的点或者 r 的父亲. 对于前者, 这是一个子问题, 直接用 (以 r 为根) 子树内度数 <3 的编号最小的点作为结果. 如果 r 一定要有右子树和父亲, 就用较小者当右子树.

  如果没有呢? 设 r 的邻接点为 x, 我们需要决策 x 当爹还是当儿. 如果 x 子树内的满足条件的最小点仍 >x, 显然当爹更优秀. 否则, 即使这一最小值 =x, 此时 x 度数 2, 让它当儿的决策空间包含当爹的决策空间, 其他情况直接形成优劣关系, 所以都应该让 x 当儿.

  最后, 预处理以 r 为根的子树最优点, 然后贪心搜一边就能求出结果. O(n).

2.「CTT 2017」「洛谷 P4226」避难所

  其实答案已经写在样例里啦. 研究 6×6×6=3×3×3×8 的一般情况: 设素数 x 是满足 x3b 的最大素数, y 是满足 y2>b 的最小素数, 那么 (xy)(xy)(xy)¯ 就会被贪心算法误判为 yyy(x3)¯. 当然, 这里需要满足 x2y>b, 一个很 OI 的解决办法是小范围暴力或者打表 (枚举所有三位数判断), 因为这个问题只会在 b 足够小时发生. 暴力复杂度毛估 O(b4logb) (所以建议打表), 大范围直接暴力扫素数可以做到 O(b1/4logb), 挺快的 w.

3.「AGC 023F」01 on Tree

  那个… 这个 trick 是不是有什么名字呢? 树形拓扑限制, 贪心向爹合并就行. 一个序列整体可以记作 (one,zero,inv), 对它 exchange argument 即有贪心策略. O(nlogn).

4.「AGC 024C」Sequence Growing Easy

  放过一道水题, 就会不想写更多不那么水的题的题解, 所以!

  填出值 k 的方案是唯一的: 放一个 [0,1,2,,k] 在它前面. 所以只有 a 值刚好和这个吻合的部分可以节约操作次数. 此外, 若 ai>ai1+1 或者这样的序列会覆盖 0 位置, 就一定无解. O(n).

5.「UR #1」「UOJ #21」缩进优化

  兔在以前的博客里鸣过警钟: a=kx+r, x,k 可以同时枚举. O(n+VlogV).

  为什么会做到 UR 的题?

6.「JOISC 2022」「LOJ #3694」一流团子师傅

  "二分答案" 的 tag 比较乱入, 实在是找不到合适的 tag 啦. 但这的确是一道很好的 learn to use binary search 的题.

  前三个子任务很好想: 我们不断尝试取出出现位置尽量靠前的一串🍡 (什么输入法糖), 每次在未用材料序列上二分出能够做🍡的最小右端点, 那么这个端点出的材料肯定要用, 反复二分 n 次就能取出一串🍡. 询问次数为 O(mnlog(mn)), 差一点点. 怎么只给这么点儿分???

  第四个子任务需要一点小小的 motivation: 我们刚才是依次为每串🍡找材料, 我们其实也可以尝试为每个材料找合适的🍡. 而一个材料可以放入🍡等价于不于🍡内已有材料重复, 也等价于放完之后, 用这串🍡以外的材料能做出 m1 串🍡. 后一个判据是可用于二分的, 我们维护🍡集合, 对🍡集合二分找合适位置即可. 询问次数 O(nmlogm), 赢.

7.「JOISC 2022」「LOJ #3695」鱼 2

  • Link & Submission.
  • 「A.数据结构-线段树」「C.性质/结论」

  和上个 solution set 里提到的思路本质类似, 我们更亲睐对静态的 "再吃不能" 的状态进行描述. 对于一条鱼 x, 若存在 l<x<r 使得 min{al,ar}>i=l+1r1ai, 那么 x 就不可能打破 [l,r] 的限制, 自然也就无法最终存活. 进一步的, (l,r) 其实让 l+1r1 内的所有鱼都不可能存活. 我们称这样的 (l,r) 为支配区间.

  若固定端点 l 分析 r, 容易发现支配区间不超过 O(nlogV) 个. 实际上支配区间显然要不包含要不相离, 所以 O(n) 的上界也存在. 我们现在就把问题转化成了两个部分: 1) 动态维护支配区间. 2) 快速处理区间询问.

  对于 1), 套用固定端点分析的方式, 当 x 被修改时, 我们仅需要拿出所有与 x 有关 (支配 x 或者以 x 为端点) 的支配区间, 将它们的贡献删除, 修改 a 值后再重新加入, 最终就只会对 O(logV) 个支配区间的贡献进行修改. 那么, 如何快速取出这些区间呢? 对于以 x 为端点的区间, 我们可以进行 O(logV) 线段树二分大力枚举到 x 的区间和翻倍的最近位置, 检查这个位置是否与 x 构成支配区间. 对于支配 x 的区间, 显然仅会以刚才枚举过的端点位置作为左右端点, 且由于支配区间互不跨越, 总共 O(log2V) 种可能的区间中也只有 O(logV) 个会有改动. 所以这里也可以大力枚举.

  对于 2), 设询问区间为 [l,r], 为了仅使用 "是否被支配" 来描述一条鱼的存活性, 我们不妨令 al1=ar+1=+ (即, 直接在处理询问前做两次单点修改). 又由于一定至少有一条鱼能存活, 所以区间中被支配次数最小的鱼的数量就是答案. 简单线段树维护一下即可.

  最终复杂度是 O(nlog2V), 精细实现可以做到 O(nlognlogV), 兔写出来非常卡常, 喜提 LOJ 最劣解 😭.​

8.「JOISC 2022」「LOJ #3696」复兴计划

  属于是把 P/B/K 三个 MST 算法枚举了一边. (

  题目等价与多次询问原图以 |xw| 为边权的 MST 边权和. MST 具有良好的可调整结构, 顺着这一点思考, 发现随着 x 的单调移动, 我们只会用 w 大的边替代 w 小的边, 而且按 w 升序尝试替代仍然优秀. 换句话说, 如果从 x=0 为初始状态向后调整, 每条边的替代目标是唯一的! 设我们用边权为 w2 的边替代边权为 w1 的边, 此时就要求 x(w1+w2)/2. 我们直接模拟求出所有替代, 按 (w1+w2)/2 排序, 和询问的 x 做双指针贪心替代边即可. 复杂度 O(mlogm+nm+q), 当然找替代边可以用 LCT 等东西优化.

9.「UR #1」「UOJ #22」外星人

  1. 人是两两不同的.

  2. 外星人是.

  3. 外星人是两两不同的.

  4. 不要去重.

  5. 如果你一定要为外星人去重, 请 %$%^&去@人&)

  将 a 升序排列. 令 f(i,r) 表示仅考虑 ai..n 时, 余数为 r 的方案数 (包含在 n 个空位中为这 ni+1 个数选位置的方案). 转移是 O(1) 的, 最终复杂度 O(nV).

10.「CF 1286D」LCC

  "碰撞" 这个事件非常的局部, 我们反而没有办法直接处理, 所以可以考虑直接按时间升序枚举碰撞事件, 我们接下来就只需要能够钦定这个事件发生 / 不发生. 用 f(i,d) 表示考虑 1i, i 的方向为 d 且满足所有事件要求的概率, 依赖于其局部性, f(i) 仅仅是一个二维向量, 可以用数据结构维护一列线性变换. 钦定事件发生 / 不发生也可以通过修改转移矩阵实现. 复杂度 O(23nlogn).

11.「CF 618G」Combining Slimes ⭐

  在数学家们苦苦寻求解析解的时候, 卑鄙的信息学家居然用数值解过题. (

  注意到格子的一段后缀被卡住时才会产生子问题, 这时这段最左端的数值得研究. 我们令 f(i,j) 表示在 i 个格子的游戏中 j 出现过的概率, 显然有 f(i,j)=f(i,j1)f(i1,j1), f(1,1)=p, f(1,2)=1p. 顺便, 我们可以表示出 j 恰好出现一次 (此时它必然留到最后) 的概率为 f(i,j)=f(i,j)(1f(i1,j)).

  接下来就能在刚才描述的子问题上 DP 了: 令 h(i,j) 表示在 i 个格子的游戏中, 最左端的格子最终为 j 时格子数值的期望总和. 那么

h(i,j)=j+k<jf(i1,k)h(i1,k)k<jf(i1,k).

注意 j 的右侧必然 <j, 除此之外无特殊限制, 所以正比于它们的出现概率求和就行.

  当然, 唯一的特殊情况是 j=1, 此时要求 j 的右侧一开始 2, 最终合并出任意的数. 看来我们还需要算一算和 f 类似, 但要求第一个数是 2 的状态 g(i,j), 有 g(i,j)=g(i,j1)f(i1,j1), g(1,2)=1p; g(i,j)=g(i,j)(1g(i1,j)). 进而得到 j=1 时的结果:

h(i,1)=1+k>1g(i1,k)h(i1,k)k>1g(i1,k).

  最终, 我们希望求出

ans=k1f(n,k)h(n,k).

  那你就要问了, 你这一堆没上界的求和让我怎么算呢?

  — 注意到所有东西关于 j 的收敛都很迅速, 所以人为限制 jL=50 即可保证精度.

  你还是不明白, 这 n=109 单次 O(1) 也算不了啊?

  — f,g 关于 i 的收敛也… 所以只需要暴力算前 L 项, 后面的东西视作以 f(L,) 或者 g(L,) 为系数的常系数齐次线性递推, 矩阵快速幂什么的就能求出来了.

  复杂度 O(L3logn), 不过带着关于精度要求的阈值算复杂度也没什么意思呢.

12.「QOJ #4219」Insects ⭐

  先想想固定黑白点集合的时候如何求答案. 问题等价于: 每个黑与右上方白点连边, 求该二分图的最大独立集. 先感知一下, 若一个白点在独立集中, 则其右上方的所有白点都在独立集中且所有黑点都不再独立集中. 因此, 最终入选的点一定能被一条从左上到右下的折线划分为两部分, 上半部分全部选白点, 下半部分全部选黑点. 我们只需要求出这条折线, 就得到答案了.

  最大独立集… 最大匹配… 我们可以发现这条折线是最小割! 我们先贪心地求出最大匹配: 按坐标降序枚举点, 枚举出黑点时向已出现的未被匹配的白点中, 高于黑点且尽可能低的白点连边, 正确性是容易证明的. 接下来, 我们构造一条不穿过匹配边的折线, 根据匹配边的贪心性质, 在不得不下降折线 (即将穿过匹配边) 时, 一定可以让折线竖直下降到匹配边的黑色端点而不穿过匹配边. 这样就能构造折线了.

  最后, 在不断加入白点时, 折线的每个位置都不会下降, 那么被折线划分开的部分点是能够永久确定会 / 不会被选择的. 我们只需要对询问整体二分, 每次决策还为确定的点即可. 复杂度 O(nlog2n).

  形式化的题解.

13.「CF 1188E」Problem from Red Panda

  不考虑可行性, 序列最终的值仅有每个位置的操作次数确定. 设操作序列为 {xn}, s=ixi, 那么最终有 ai=ai+kxis, 这里要求 mini{xi}=0 就能建立双射.

  接下来, 还需要描述 {xn} 的可行性. ai=ai+kxis0xi(sai)/k, 同时 xi0, 进而有 s=ixiimax{0,(sai)/k}. 这里很巧妙, 虽然仅仅是必要条件, 但限制与 x 具体取值无关, 我们就可以方便地描述 "每个时刻都能进行下一步操作" 了! 因此, {xn} 的合法条件为:

t[0,s], ti=1kmax{0,(tai)/k}.

  最后, 枚举 s, 用一些桶快速维护右式, 判断合法性后隔板出 {xn} 即可求出方案数. 显然 smaxi{ai}, 否则 mini{xi}>0. 故复杂度 O(n+maxi{ai}).

14.「CF 1023G」Pisces ⭐

  • Link & Submission.
  • 「A.数据结构-平衡树」「C.性质/结论」

  注意第一步转化: 建立 "一群鱼能到另一群鱼" 的偏序关系, 我们希望求出的就是带权最长反链. 即找到一组数量最多的鱼群集合, 使得两两鱼群不可在限定时间内到达.

  接下来需要用树的性质来简化讨论. 显然, 仅仅研究 r 子树的情况, "S 是反链" 等价于 S 在每棵 r 的孩子的子树内是反链, 且不存在能跨过 r 相互到达的鱼群. 那么我们可以得到一个简单的 DP: f(u,a,b) 表示 u 子树内到达 u 的最早时间是 a, 允许 u 被子树外的鱼群到达的最早时间是 b 时, u 子树内的最大反链大小.

  优化一下? 转移的时候我们像是在对 [b,a] 做区间交, 那么我们可以从一开始就值抽取区间内的点保存信息. 由于限制关系是 <, 所以得取一些非整点, 当然所有时间 ×2 就可以只取整点了. 设新的状态为 f(u,t), 讨论其对父亲贡献时的情况, 设父边边权为 w:

  • 若不选 u 中的鱼群, 那么 t 可以在 [tw,t+w] 里取最大值.
  • 如果选了 u 中的鱼群, 设为 (d,f), 那么子树贡献是 f(u,d), 对父亲的贡献也是在 [dw+1,d+w1] 内取最大值.

  接下来是维护工作, 用平衡树维护差分列, 这样取最大值操作就变为差分列的移动, 还需要用堆来抵消交错的正负差分位置. 最后叠加贡献就直接启发式合并差分列即可. 复杂度 O(n+mlog2m).

15.「UR #1」「UOJ #23」跳蚤国王下江南 ⭐

  • Link & Submission.
  • 「A.图论-圆方树」「A.数学-多项式」「A.树论-点分治/点分树」

  应该叫… 圆方树上有根点分治 FFT 板题. (?

  建圆方树嘛, 不过其实这里只关心从 1 到原点的信息, 所以并不需要建出方点, 直接把信息连在方点父亲上即可. 最终我们把问题转化成这样的形式: 给定一棵树, 每条边上的权值形如 (xa+xb), 求根到所有点的权值乘积之和. 保证任意竖直路径的次数低于 n.

  然后我们可以对这棵有根树进行点分治. 设希望求出 x 子树内所有点到 x 的信息, 有根树点分的基本思想大概是:.

  • 取出 x 子树的重心 r, 并递归求解 r 的子树.
  • "序列分治" 求出 rx 的信息, 将它与从 r 子树内到 r 的信息合并, 贡献入答案.
  • 删除 r 子树, 再次递归 x 子树.

  不平凡的点是, "序列分治" 是不必要的, 我们可以先递归 x 子树, 此后 xr 的路径上会出现一列重心, 我们从 r 的父亲开始不断跳 "重心 子树根" 一路跳上去, 利用已经求出的信息合并, 以此保证复杂度.

  这题写个 FFT 就好了. 跳重心的复杂度是 T(n)=O(nlogn)+T(n/2)=O(nlogn). 最终复杂度 O(nlog2n). 注意多项式运算 ff+(xa+xb)g 的复杂度要求做到 O(degg), 不然 T 成 joker.


  重庆的春 "哽咽" 了好几天, 气温暴跌二十多度, 差点冻死. (

posted @   Rainybunny  阅读(199)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示