Examples

2023-9-17 #69 我相信我值得被你所深爱

——闹闹《我值得吗?》

太厉害了我的晓莉 q🥰🥰🥰🤤🤤🤤😇😇😇。

488 P9535 [YsOI2023] 连通图计数

分讨 m 的取值:

m=n1,那么 ai 即一个点的度数,于是可以使用 prufer 序列计算方案数(多重组合数)。

没想到考察圆方树,输!

注意到,ai 实际上在描述圆方树中某一圆点的度数。

m=n 时,我们可以计算出环的大小,使用 prufer 计算方案数,并乘上环排列方案数除二。

m=n+1 时有两种情况,有一个方点时,同样能得到其度数并 prufer,而方点的构建方案数为 (n2)(n2)!((n2)3)3!(考察三度点,并注意三度点之间的三条链至多一条长度为 0,因此还需减三)。

有两个方点时,可以枚举其中一个方点的度数来计算,注意需要减去两个方点相连的方案数。

复杂度 O(n)

489 P9536 [YsOI2023] Prüfer 序列

考虑 prufer 序列还原树的方法——从前往后扫描序列,每次选择编号最小的一度点连接当前位置上的编号,并将该点度数减一,最后将唯一未被删除的两个点相连(一定有一个为 n)。

这启发我们记录被删除的点,并钦定一些点为一度点(因为我们不能得知度数序列)。记 fi,S,T 表示考虑了序列上 [i,m] 所有数,一度点集合为 S,被删除点集合为 T 的方案数,gi,j,S,T 表示对应情况 jn 的距离之和,状态数 O(3nnm),转移 O(1)

考虑优化对 S,T 的记录,注意到在删除 x 某个儿子后我们仅会检查 x 是否要并入 S,容易证明 S 在去除至多一个位置后,其余位置编号均严格比 T 中任意编号大(这事实上也给出了线性 prufer 序列还原树的方法),于是记录 S,T 只需 O(2nn2) 的信息量,可以做到 O(2nn3m)

这里的具体实现比较复杂,我压 S 信息的方法是记录 S 的最小值与 T 的最大值。

注意到 g 状态太多还需继续压缩,注意转移时我们一定会删去 S 的最小值,因此若 S 最小值是游离在外的,我们事实上只需知晓其是否等于 j,于是我们可以记 0/1/2 分别表示:其他/等于 j/不等于 j,且比 T 最大值更大,分讨可知可以转移。

常数较大,一个神秘的卡常方法是数组不开 2 的幂次大小。

标算的记录方法是:若 S 最小值游离在外且不为 j,我们可以假设 S 形态为 T 最大值拼上这段后缀,这样我们就只需要记录 0/1 表示是否等于 j 了。

490 P9537 [YsOI2023] CF1764B

考察游戏结束情况——若一个人无法操作,除非其集合形成等差数列,否则对手集合大小一定大于其集合大小。

于是我们大可先用集合大小估计胜负情况,并尝试修正等差数列的情况。

注意到结束时对手的集合应是 {d,2d,,(n1)d} 形式,因此其给出的数也是 kd 形式,于是我们能分两个部分讨论:

  • 开局即输,枚举 d,那么等差数列长度不超过 Vd,使用 bitset 暴力 b&=b<<d 即可统计,复杂度 O(V2logVw),常数较小;
  • 操作了至少一步再输,那么输家的集合最后一定形如 {kd,(k+1)d,,(k+n1)d},我们还需继续探究如何生成两人的集合。

假设最终态满足 k=1,输家必须初始拥有 (n1)d,nd,事实上该条件在 k=1 时充要,因为每次赢家集合大小为 m 操作时,其可以构造至少 m1 个小于 (n1)d 的值,而输家只有 m2 个这样的值。

手模发现 k>1 时起始态限制严格强,因此我们可以只统计上述条件,分先后手讨论,求和是范德蒙德卷积形式,这一部分复杂度 O(VlogV)。注意这里的统计不能与开局输的统计重复,我们只需在基础上减去选择两段等差数列的方案数,容易计算。

总复杂度 O(V2logVw+VlogV)

491 P9388 [THUPC 2023 决赛] 先人类的人类选别

怎么场上没一眼鉴定出来啊,好像不难?与 408 HDU6423 Rikka with Bubble Sort 的思路类似。

法一:

一个显然的性质是我们只会 swap 为非严格前缀最小值的数(我们称其为好数),而且可以将一段后缀的好数整体右移(注意不影响其他位置)。

进一步地,我们能发现成为了好数的值操作后仍然是好数,成为了好数的位置操作后仍然是好数。我们可以单独开两棵线段树维护好数(序列与值域上),查询区间和可以线段树二分出在这段区间内的好数区间。

接下来还需维护每个数何时变为好数,我们可以维护所有数的反序表,注意一次操作会将所有值小于等于 x 的好数反序表更新,但是直接维护要求矩形减与最小值查询,这是不能接受的。

我们维护非好数的非严格前缀最小值,一次修改中我们容易得知哪些最值被改为好数,并动态维护最值,可以发现其不会漏掉任何新成为好数的位置。而我们只需维护这些最值的反序表,找到新加入最值的数并重新计算它们的反序表,都可以使用线段树进行模拟,复杂度 O((n+m)logn)

好吧还是有点繁琐的,但只想到这个做法。

法二:

注意到操作之间顺序互不影响,更进一步地我们能用堆描述操作可重集 S 对一个前缀 [1,i] 的影响——将 [1,i] 的数与 S 放入堆中,并取出前 i 大以某种顺序放回 [1,i]

每次查询只需取两个前缀和相减,于是我们并不需要维护每个位置的值,使用主席树上二分计算来回答询问即可,复杂度 O((n+m)logn)

492 uoj#596. 【集训队互测2021】三维立体混元劲

ei 太强了。

容易得到一般图的 EGF,我们需要进行高维多项式 ln 得到连通图的 EGF。

回顾二维多项式操作,二维 DFT 的实现方法是对多项式两维各 DFT 一遍。直觉上我们可以类似地处理高维 DFT,但别忘了 DFT 时需倍长值域,因此复杂度上会凭空多出 2k,这并不能接受。

我们将一个高维下标看作一个 (n1,n2,,nk) 进制数,我们要做的即“对所有相加不会进位的数对做卷积”,一个简单的想法是类似子集卷积,添一维记录各数位的和,但值域过大,并不好处理。

但是有一个类似的构造:记占位函数 χ(x)=xn1+xn1n2+,虽然值域仍然较大,但其避免了进位变 0 的情况,于是 χ(x)+χ(y) 应当与 χ(x+y) 非常接近,更进一步有 χ(x)+χ(y)[χ(x+y)k+1,χ(x+y)]

还没写,具体怎么实现就先不管了。

493 CF1707D Partial Virtual Trees

相邻不同这一限制比较烦,不妨将其容斥掉,我们只需 dp 求出任意固定长度的合法序列长度,于是设 fi,j 进行 j 次操作,i 内还有点的方案数。

考虑分讨 ij 时刻是否存在,存在时平凡,不存在时我们考虑枚举失去 i 的时刻 k

fi,jk<jxfx,kyxlpfy,l

预处理前缀和,以及后面那一堆前后缀积后,前缀和后容易 O(|son(i)|) 算出 fi,j,复杂度 O(n2)

494 CF1707E Replace

结论:

fk(l,r)=li<rfk(i,i+1)

倍增处理 f2k(i,i+1) 即可。

这是怎么想到的呢?

495 CF1707F Bugaboo

迷迷糊糊。

一个浅显的性质:任意异或和为 0 的序列都能作为一次变换的结果。

类似地,考虑如何还原上一层——去除最后一个数,在前面任意添加一个数并作前缀异或和。

n 为奇数,我们能唯一地确认前面添加的数是多少,因此只要异或和为 0,我们就能任意地向前还原。

n 为偶数时,不妨考察 n=2h 的情况:

我们尝试先完成 bugaboo 的判定。注意到若 t 为偶数,我们可以将两次相邻操作合并,于是环上可以分成奇偶两部分递归处理。这一策略相当优秀,在 t 为奇数时,我们手玩后也能发现其即在 t1 次的基础上,额外要求两部分初始时异或和相等。

形式化地,我们设计函数 f(S,t) 表示我们考察下标集合 S,需要在之前进行 t 次变换,返回是否合法,以及最初序列的异或和,转移容易刻画,复杂度 O(n+(m+q)logn)(决策树类似线段树,建树线性,修改 O(logn))。

(事实上这里 S 的划分递归与 FFT 的蝴蝶变换一致)

接下来考虑计数,暴力地增加一维 k 表示我们要求这个集合初始时异或和为 k。若 t 为偶数,转移为 XOR 卷积;若 t 为奇数,转移为点乘。容易发现固定前两维时,k 这一维 dp 值只有两种情况:只有一个位置有值 (2w)v,或者全为 0(2w)v(归纳易证),于是可以 O(1) 合并,维护方法与判定是一致的。

扩展到 n 任意,我们将其表示为 n=2h(2k+1),手动建出 h 层的决策树后化作 n 为奇数情况,之后一定合法。具体地,我们即在序列 bi=jmod2h=iaj 上应用前面提到的算法,但注意 t2h 时需限定 bi=0

posted @   xiaoziyao  阅读(203)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
历史上的今天:
2022-09-17 2022-9-17 #28 请允许我独自探访这场戏的结局
点击右上角即可分享
微信分享提示