2024.1 做题记录

洛谷 4785 [BalticOI 2016 Day2] 交换

xxx/2\lfloor x / 2 \rfloor 连边,交换操作即交换一对父子.我们需要贪心地将最小值换到根上.

容易发现处理完一个节点后,其两子树变为独立的子问题,故考虑如何处理一个节点.

考虑 a,b,ca, b, c 三个节点,其中 aabbcc 的父亲,显然当最小值取到 xax_axbx_b 上时,均可以以唯一方式交换到 aa 上,故方式确定.

当最小值取到 cc 时,我们发现需要讨论 xax_axbx_b 如何分配给 bbcc.事实上根本不用讨论,暴力搜出所有状态即可.因为一个节点可能被分配的值只有其祖先及祖先的兄弟上的值,故总状态数 O(nlogn)O(n \log n)

洛谷 9962 [THUPC 2024 初赛] 一棵树

fu,if_{u, i} 表示 uu 子树选 ii 个节点染成黑色的代价,考虑合并子树,有转移:

fu,i+jminfu,i+fv,j+k2jf_{u, i + j} \xleftarrow{\min} f_{u, i} + f_{v, j} + |k - 2j|

形如一个 (min,+)(\min, +) 卷积,由于 k2j|k - 2j| 是一个关于 jj 的凸函数,故容易归纳证得 fuf_u 是凸的.

然后就是套路地用平衡树维护差分序列,启发式合并做 (min,+)(\min, +) 卷积.复杂度 O(nlog2n)O(n \log^2 n),至少我只能分析到这里.

洛谷 6803 [CEOI2020] 星际迷航

首先可以通过换根 DP 求出 sus_u 表示原树上从 uu 点出发是不是必胜的.然后对于第 ii 棵树,点 uu 若接上一个点 vv 满足 sv=0s_v = 0,那么 uu 就赢了.

考虑 010 \to 1 怎样连是合法的,若 11 号点是必胜点,那么树上的点可以 xjb 连到下一棵树上,只要不改变 11 号点的状态就行;若 11 号点是必败点,那么必须有一个会影响 11 号点状态的点连到下一棵树上的必败点.

由上面的分析,我们不妨设 fuf_u 表示会影响 uu 状态的点数,若我们计算出了考虑 1D1 \sim D 的所有连接方案,11 号树上的必败 / 必胜点数,那么答案就可以轻松算出.

不妨设 gi,0/1g_{i, 0 / 1} 表示考查 iDi \sim D 的所有连接方案,第 ii 棵树的非必胜 / 必胜点数和,有转移:

gi,0=su=0(nfu)gi+1,0+su=1fugi+1,0+su=0ngi+1,1gi,1=su=1(nfu)gi+1,0+su=0fugi+1,0+su=1ngi+1,1\begin{aligned} g_{i, 0} &= \sum_{s_u = 0} (n - f_u) g_{i + 1, 0} + \sum_{s_u = 1} f_u g_{i + 1, 0} + \sum_{s_u = 0} n g_{i + 1, 1} \\ g_{i, 1} &= \sum_{s_u = 1} (n - f_u) g_{i + 1, 0} + \sum_{s_u = 0} f_u g_{i + 1, 0} + \sum_{s_u = 1} n g_{i + 1, 1} \end{aligned}

显然可以矩阵快速幂转移.

洛谷 3735 [HAOI2017] 字符串

考虑如何判定两个串 SSTT 相等.首先要 S=T|S| = |T|,然后是 lcp(S,T)+lcs(S,T)+kS\operatorname{lcp}(S, T) + \operatorname{lcs}(S, T) + k \ge |S|

考虑对所有模式串,枚举结束位置为 ii 的一个前缀,那么能被计入答案的子串首先要与这个前缀匹配,且其 i+k+1i + k + 1 开始的后缀也要和模式串从 i+k+1i + k + 1 位置开始的后缀匹配.

刻画多串匹配问题,容易想到 AC 自动机.对所有模式串及其反串建立 AC 自动机,设 pip_iSS 结束位置为 ii 的前缀匹配到的节点,qiq_iSS 开始位置为 ii 的后缀倒着匹配到的节点.对于某个模式串,类似地设出 fi,gif_i, g_i,那么 SS 中一个位置 ii 能被 TT 中的某个前缀 jj 计入答案的条件是 pip_ifjf_j 的子树中,且 qi+k+1q_{i + k + 1}gi+k+1g_{i + k + 1} 的子树中.拍到 dfs 序上之后显然是一个二维数点,直接做即可.

乱写一通后发现这玩意不大对啊!对于 SS 的一个能计入模式串 TT 的答案的子串 SS^\prime,设 SS^\primeTT 第一次不相同的位置是 ii,最后一次不相同的位置是 jj.若 ji+1<kj - i + 1 < k,这个子串会被统计多次.

考虑如何去重.我们钦定这个子串在枚举 TT 的前缀 i1i - 1 时被统计.考虑每次被统计到的含义,我们相当于钦定了一段长度为 kk 的区间不管,要求剩下的前后缀匹配.我们考虑将钦定的区间的第一个元素去掉,然后再统计满足要求的区间,显然只有前缀 i1i - 1 不会被计入贡献.这相当于令 kk1k \leftarrow k - 1 后再运行一遍上述算法.用第一次算得的答案减去这样统计到的答案即可.

注意计算第二部分时,[i,j][i, j] 贴着子串开头结尾的情况不能计入(即匹配空前后缀的情况).此时贡献只会在第一部分中被统计一次.

洛谷 4482 [BJWC2018] Border 的四种求法

询问相当于找到一个最大的 ii 满足 i<ri < r,且 ilcs(S[:i],S[:r])+1li - \operatorname{lcs}(S[:i], S[:r]) + 1 \le l

直接建出原串 SAM 的 parent 树,设以 ii 结束的前缀对应的节点为 pip_i,问题转化为求最大的 ii 满足 i<ri < rilenlca(pi,pr)+1li - \mathrm{len}_{\operatorname{lca}(p_i, p_r)} + 1 \le l

考虑一个经典技巧,我们倒着扫描线,每扫到一个询问的 rr 就将其挂到祖先链上.尝试用 ii 回答询问的时候爬祖先链,过程中第一次碰到某个询问 [l,r][l, r] 所在的节点即 pip_iprp_r 的 lca,直接判定即可.

parent 树的深度没有保证,考虑优化掉爬链的过程.将 parent 树重链剖分,设当前尝试用 ii 回答询问.考查每个询问 [l,r][l, r]prp_r 可能在 pip_i 到根路径上某条重链上节点 uu 的轻子树中,此时 lca(pi,pr)=u\operatorname{lca}(p_i, p_r) = u,这一部分通过将询问 [l,r][l, r] 挂到 prp_r 到根路径上每条重链顶的父亲上,限制可化为 ilenu+1l    il+lenu1i - \mathrm{len}_u + 1 \le l \iff i \le l + \mathrm{len}_u - 1,尝试回答询问时贪心选出重链前缀中最大的 l+lenu1l + \mathrm{len}_u - 1 对应的前缀回答即可.

prp_r 还可能在 pip_i 到根路径上某条重链的底端节点 uu 的重子树中,但是这一部分的限制可以直接放宽到 uu 的子树,因为此时 lca(pi,pr)\mathrm{lca}(p_i, p_r) 肯定在 uu 的子树中,而在轻子树的部分此前已经处理过了,可以直接丢掉;其他情况的 lca 一定取到 uu.故限制可化为 ilenu+1l    ilenul1i - \mathrm{len}_u + 1 \le l \iff i - \mathrm{len}_u \le l - 1,贪心选子树中 ll 最大的询问回答即可.

洛谷 5155 [USACO18DEC] Balance Beam P

fif_i 表示从 ii 出发的最大期望收益,有 fi=max{(fi1+fi+1)/2,ai}f_{i} = \max\{(f_{i - 1} + f_{i + 1}) / 2, a_i\}

然后不知道怎么注意到 max\max 中的第一项是等差数列的判定条件,那么 fif_i 是凸的,直接求出凸壳即可.

洛谷 4745 [CERC2017] Gambling Guide

考虑设 fuf_u 表示 uu 到终点的期望花费,有方程:

fu=1+1du(fv<fufv+fvfufu)f_u = 1 + \frac{1}{d_u} \left(\sum_{f_v < f_u} f_v + \sum_{f_v \ge f_u} f_u\right)

考虑按照 ff 从小到达的顺序确定 ff 的值,又 fn=1f_n = 1,故考虑从 nn 开始,每次选出已知的最小的 fuf_u 递推邻接节点的 ff,由于每次递推一定会使值增大,故正确性有保证.

UOJ 553 己酸集合

(xi,yi)(x_i, y_i) 在以 (0,zj)(0, z_j) 为圆心,RjR_j 为半径的圆里,那么有

xi2+(yizj)2Rj2    2yizj+xi2+yi2Rj2zj2{x_i}^2 + (y_i - z_j)^2 \le {R_j}^2 \iff - 2 y_i z_j + {x_i}^2 + {y_i}^2 \le {R_j}^2 - {z_j}^2

若将每个点 (xi,yi)(x_i, y_i) 看成点 (yi,xi2+yi2)(y_i, {x_i}^2 + {y_i}^2),那么询问就是查询直线 y=2zjx+Rj2zj2y = 2 z_j x + {R_j}^2 - {z_j}^2 下方的点数.

直接半平面数点即可.

UOJ 422 【集训队作业 2018】小 Z 的礼物

先 Min-Max 容斥一下,设 E(S)E(S) 表示集合 SS 中有元素被覆盖到的期望步数,那么答案为

S(1)S+1E(S)\sum_S (-1)^{|S| + 1} E(S)

考虑如何计算 E(S)E(S),由于每轮覆盖独立,故只用计算一轮覆盖到 SS 的概率 P(S)P(S),有 E(S)=1/P(S)E(S) = 1 / P(S).设选取后能覆盖到 SS1×21 \times 2 矩形数为 cSc_S,又 1×21 \times 2 矩形总数为 n(m1)+m(n1)n(m - 1) + m(n - 1),故 P(S)=cS/(n(m1)+m(n1))P(S) = c_S / (n(m - 1) + m(n - 1)).此时答案可写作

S(1)S+1n(m1)+m(n1)cS=(n(m1)+m(n1))S(1)S+1cS\sum_S (-1)^{|S| + 1} \frac{n(m - 1) + m(n - 1)}{c_S} = (n(m - 1) + m(n - 1)) \sum_S \frac{(-1)^{|S| + 1}}{c_S}

考虑如何计算后面那个 \sum,发现 SS 的个数太多,且 cSc_S 在分母上,可能的改变形式却是加法,故不能在这上面做文章.但 cSc_S 的值域是 O(nm)O(nm),故考虑设

fi=cS=i(1)S+1f_i = \sum_{c_S = i} (-1)^{|S| + 1}

后面那个 \sum 的值即为

ifii\sum_i \frac{f_i}{i}

考虑如何计算 fif_i然后就不会了,由于只有 n6n \le 6,考虑按列升序进行轮廓线 dp.设 fj,i,S,xf_{j, i, S, x} 表示考虑到了第 jj 列的第 ii 行,轮廓线上 SS 中元素状态为 SScS=x(1)S+1\sum_{c_S = x} (-1)^{|S| + 1} 值.转移考虑 (i,j)(i, j) 加不加入到之前的 SS 中.

LOJ 6509 「雅礼集训 2018 Day7」C

11 点为黑点,00 点为白点.

这个随机过程和树的形态一点关系都没有,故只需计算出离开每个节点的期望次数,乘上这个节点到其他节点的平均距离求和即为答案.又同种颜色的点无法被区分,故离开次数的期望相同.

不妨设 hi,jh_{i, j} 表示有 ii 个黑点时,颜色为 jj 的点的期望离开次数.有方程

hi,0=ni1nhi+1,0+1n(hi+1,1+1)+inhi1,0hi,1=i1nhi1,1+1n(hi1,0+1)+ninhi+1,1\begin{aligned} h_{i, 0} &= \frac{n - i - 1}{n} h_{i + 1, 0} + \frac{1}{n} (h_{i + 1, 1} + 1) + \frac{i}{n} h_{i - 1, 0} \\ h_{i, 1} &= \frac{i - 1}{n} h_{i - 1, 1} + \frac{1}{n} (h_{i - 1, 0} + 1) + \frac{n - i}{n} h_{i + 1, 1} \end{aligned}

移项可得递推形式,那么若设 x=h1,0,y=h1,1x = h_{1, 0}, y = h_{1, 1},所有 hh 均可表示成关于 x,yx, y 的二元一次方程,又已知 hn,0/1h_{n, 0 / 1},那么可解出 x,yx, y,然后就能算出所有的 hh

Codeforces 914F Substrings in a String

string suffix structures?感觉不如 std::bitset

考虑一个暴力.考虑维护一个能够匹配的字串的开始位置构成的集合,初始为全集,我们顺序枚举模式串中的字符,将该位失配的位置踢出集合,最后剩下的就是合法子串的开始位置.显然可以用 bitset 优化.

Codeforces 643E Bear and Destroying Subtrees

容易想到设 fu,if_{u, i} 表示 uu 子树深度 i\le i 的概率,有转移:

fu,i=v12(fv,i1+1)f_{u, i} = \prod_v \frac{1}{2} (f_{v, i - 1} + 1)

每次重新 dp 显然不可接受,发现我们需要输出实数,且允许 ϵ=106\epsilon = {10}^{-6} 的误差,又我们每层转移都有系数 1/21 / 2,故一个值在经过 log1/ϵ60\log 1 / \epsilon \approx 60 层转移后就可以忽略了.所以我们可以将转移的第二层限制到 log1/ϵ\log 1 / \epsilon,这样我们的复杂度就是 O(nlog1/ϵ)O(n \log 1 / \epsilon)

Codeforces 183D T-shirt

考虑设 fi,j,kf_{i, j, k} 表示考虑了前 ii 个人,第 jj 种尺寸有 kk 个人适合的概率.有转移

fi,j,kfi1,j,k1pi,j+fi1,j,k(1pi,j)f_{i, j, k} \leftarrow f_{i - 1, j, k - 1} p_{i, j} + f_{i - 1, j, k} (1 - p_{i, j})

那么可计算第 ii 种尺寸准备 jj 件的期望收益,不妨设为 gi,jg_{i, j},有

gi,j=xjxfn,i,x+jx>jfn,i,xg_{i, j} = \sum_{x \le j} x f_{n, i, x} + j \sum_{x > j} f_{n, i, x}

然后把 gig_i 全部卷起来就是答案.

然后直接暴力做显然寄了.打表可以发现,gig_i 是凸的.考虑进行一个 Minkowski 和合并凸包,即对差分序列归并.由于差分是顺着算的,显然可以每次选出最大的差分,然后计算对应位置的下一项,这样就可以保证复杂度.

LOJ 3042 「ZJOI2019」麻将

计数部分的思路是计算摸了 ii 张牌还没胡的概率,然后求和即得胡牌期望次数.

考虑如何判定一副牌不是胡的.首先可以简单判掉有 77 个对子的情况,考虑判定有 11 个对子和 44 个面子的情况.考虑设 fi,j,kf_{i, j, k} 表示考虑了前 ii 种花色的牌,保留了 jj 对形如 (i1,i)(i - 1, i) 的牌对和 kk 个单独的 ii 时的最大面子数.转移考虑插入 xx 张第 ii 种花色的牌,组成 aa(i2,i1,i)(i - 2, i - 1, i)bb(i1,i)(i - 1, i)ccii.有转移

fi,b,cfi1,a,b+a+xabc3f_{i, b, c} \leftarrow f_{i - 1, a, b} + a + \left\lfloor \frac{x - a - b - c}{3} \right\rfloor

多记一维 0/10 / 1 表示当前是否保留过对子即可判定不是胡的.

考虑造个自动机,其中字符集为 0,1,2,3,4{0, 1, 2, 3, 4},表示牌数,我们期望这个自动机可以识别所有不胡的状态.利用上文中的方式,可以将状态设为二元组 (ct,f0/1,a,b)(\mathrm{ct}, f_{0 / 1, a, b}),其中 ct\mathrm{ct} 是当前最多的对子数,ff 的定义与上文类似,注意由于要塞到自动机上,第一维没有意义,要丢掉.

由于面子最多有 44 个,直觉告诉我们这个自动机的状态不多.事实上确实不多,搜出来貌似是 20912091 个.

然后就可以重新设 gi,j,ug_{i, j, u} 表示考虑了前 ii 种花色,共有 jj 张牌,在自动机上的状态 uu 时的方案数.转移枚举自动机上的出边,注意相同花色的牌之间是区分的,且需保留题目中已给的牌,故设当前花色 iixx 张牌,需乘上系数 (4aixai)\binom{4 - a_i}{x - a_i}

LOJ 3956 「联合省选 2023」城市建造

由于建边后所有城市联通,又一开始只有 tt 个联通块,故每个联通块都需要选出 11 个城市用于连边,等价于不能有两个选出的城市处于相同联通块中.对这样的原图计数等价与对点集 SS 计数,满足 S=t|S| = t 且删除 SS 导出子图中的边后,给定的图构成 tt 个联通块,且联通块的大小相差 kk

先不管联通块大小的限制来考虑我们选出的点集具有的性质.我们发现我们选出的点集必须构成联通块,并且若一个点双中有 2\ge 2 个点被选择了,我们就必须要选择整个点双.

性质和点双有关,考虑建出圆方树,称选择一个圆点为将这个圆点加入点集,选择一个方点为将其对应的点双加入点集.令 sizv\mathrm{siz}_v 表示 vv 子树中圆点的个数.

先考虑 k=0k = 0 的时候怎么做.我们可以先枚举联通块大小 BB,容易发现枚举量是 d(n)d(n) 级别.又发现若重心不被选择的话则一定不合法,故考虑以重心为根 dp.容易发现不选择方点的状态没用,故设 fuf_u 表示 uu 子树内,uu 为方点时钦定选择,uu 为圆点时可选可不选,满足选择合法,且删除点集导出子图中的边后联通块大小均为 BB 的方案数.

  1. uu 为方点时,所有子树的方案独立,有 fu×fvf_u \xleftarrow{\times} f_v

  2. uu 为圆点时,对于 sizv<B\mathrm{siz}_v < Bvv,他们需要和 uu 处在一个联通块,剩下部分的方案独立,故有

fu=[1+sizv<Bsizv=B]sizvBfvf_u = \left[1 + \sum_{\mathrm{siz}_v < B} \mathrm{siz}_v = B\right] \prod_{\mathrm{siz}_v \ge B} f_v

这一部分复杂度为 O(nd(n))O(n d(n))

再考虑 k=1k = 1 的时候怎么做.继续枚举 BB,钦定所有联通块大小 {B,B+1}\in \{B, B + 1\},容易发现枚举量仍然是 d(n)d(n) 级别.继续考虑 dp,类似地设出 ff,考虑转移.

  1. uu 为方点时,所有子树方案独立,有 fu×fvf_u \xleftarrow{\times} f_v

  2. uu 为圆点时,所有 sizv<B\mathrm{siz}_v < B 的子树都要和 uu 连在一起,所有 sizv>B\mathrm{siz}_v > B 的子树都不能和 uu 在一起,方案独立,这部分转移和 k=0k = 0 时类似.若没有 sizv<B\mathrm{siz}_v < B 的子树,那么我们可以考虑用 sizv=B\mathrm{siz}_v = B 的子树和 uu 拼出一个大小为 B+1B + 1 的联通块.考虑所有 sizv=B\mathrm{siz}_v = B 的子树:

    1. 若存在没有合法选择方案的子树(即 fv=0f_v = 0),那么这个子树必须要和 uu 连在一起,其他 sizv=B\mathrm{siz}_v = B 的子树都要断开,方案独立.显然这样的子树最多只能存在一个.有转移

    fu+sizv>Bfvf_u \xleftarrow{+} \prod_{\mathrm{siz}_v > B} f_v

    1. 若不存在没有合法选择方案的子树,那么可以随便选一个和 uu 连在一起.有转移

    fu+v[sizv=B]×sizv>Bfvf_u \xleftarrow{+} \sum_v [\mathrm{siz}_v = B] \times \prod_{\mathrm{siz}_v > B} f_v

    注意到若我们的方案中所有联通块大小均为 xx,那么在计算 B=x1B = x - 1B=xB = x 时会被算两遍,需要减去 k=0,B=xk = 0, B = x 的方案.

总复杂度 O(nd(n))O(n d(n))

Codeforces 1043G Speckled Band

口胡口胡口胡口胡口胡口胡口胡口胡口胡口胡.

容易注意到若区间内不存在两个相等的字符,那么不存在划分方案.否则答案 4\le 4

开始对答案分类讨论.不妨设给出区间对应的子串为 TT

  1. 答案为 11 时,TT 有整周期,哈希判一下即可,容易做到单次询问 O(nlogn)O(n \log n)

  2. 答案为 22 时,则 TT 必定形如 ABAABAAABAAB,后者忘了咋做,回去问下 ckain.前者直接使用 border 的四种求法 的做法解决,单次询问 O(log2n)O(\log^2 n)

  3. 答案为 33 时,只可能形如 ABACABACACCBACCB,前者只需判断 TlT_l 是否在 TT 中出现过,后者和答案为 22 时的 AABAAB 情况类似,一样解决即可.

  4. 其他情况答案为 44

总复杂度 O(nlog2n)O(n \log^2 n)