记录(1)
1. [ARC164F] Subtree Reversi
树上带有依赖性的决策题,考虑缩减树。
首先,设 \(v\) 为先手的得分减去后手的得分,先手的目标是最大化 \(v\),后手的目标是最小化 \(v\)。
首先一个观察是,如果局面上有 \(+1\) 叶子,那么很显然选择这个叶子一定是最优的。
进一步考虑,如果都是 \(-1\) 叶子,应该如何抉择下一步删哪个。如果一个叶子选了不会暴露父亲,那么选它没问题。否则如果我选了这个叶子 \(x\),对手一定会选择 \(+1\) 的父亲 \(fa_x\),下一步还是该我再操作,那么我一定会选择父亲的父亲 \(fa_{fa_x}\)。那么相当于我平白无故地得到了 \(-2\) 的代价,等价于给 \(fa_{fa_x}\) 的点权增加 \(-2\)。归纳做下去即可。
这样扩展后一个点的点权不一定是 \(\pm1\),但是仍然可以按照点权从大到小贪心选取。
理性理解这个很类似树剖的结构,只有在一个结点的重儿子被删掉之后才会导致这个结点暴露,而轻儿子之中如何选择都是没有副作用的。因此可以按照点权贪心选取。选择重儿子后双方的策略都是确定的,因此可以按照策略缩减,归纳。
2. [PA 2010] Termites
上一题是缩相邻三个点,这个题是缩相邻三个数。
首先,设 \(v\) 为先手的得分减去后手的得分,先手的目标是最大化 \(v\),后手的目标是最小化 \(v\)。
对于 deque。如果有相邻三个 \(x,y,z\),满足 \(x\le y,y\ge z\),考虑一旦一方选择了左右较小的数,另一方一定会选择中间较大的数,因此对这三个数的策略是固定的,将三个数变为一个数 \(x+z-y\),答案不变。重复操作直到不存在峰,序列一定单谷。
对于 stack。考虑如果有相邻两个 \(x,y,z\),满足 \(x\le y\),可以缩成 \(x+z-y\)。重复操作,直到序列变为单调递减。
将局面所剩的所有数拆散排序之后,显然答案一定是一个交错和。可以证明两人都有策略取到这个数值。
一种好写的方式是将序列末尾附加一个 \(-\infty\),并将序列视为环形的。这样可以避免对 deque 和 stack 分开讨论。
博弈论解题的关键 发现策略的确定性:如果某一个子结构的双方策略确定,可以对其缩减,进行归纳处理。 这也是一个博弈论题能做的必要条件。如果一个题的策略真是完全随机、毫无规律的,那么也很难去做。
3. [AGC054D] (ox)
限制为 () 构成合法括号序列,且 x 外部至少被一个 () 包裹。
一个字符集大小为 \(4\) 的排列相邻交换问题。考虑压缩字符集,一种经典的想法是将序列划分为几个子序列,子序列内部不会交换。
ox 之间一定不会发生交换。因为如果交换,唯一的目的是想把 x 挤进一对括号里面,而这样不如主动移动括号。
如果 () 本身已经构成合法括号序列,则 () 之间一定不会发生交换。因为如果发生了交换,还是想扩大覆盖的面积,而这样不如直接移动 x。
如果 () 构成的子序列 \(s\) 本身不构成合法括号序列,那么用最少的次数转化为合法的括号序列 \(t\),之后不会发生交换。因为任意一个将 \(s\) 变为合法的括号序列过程必定经过中间状态 \(t\),之前说过,在合法括号序列的基础上移动不优。
理性的证明可以通过分类讨论说明,过于繁琐,对做题有害无益,感性理解是足够的。
因此总结来看,ox 构成的子序列 \(A\) 和 () 构成的子序列 \(B\) 是已经确定的。可以用一个 \(O(n^2)\) 的 DP 将两个序列归并。如果原先 \(a\) 在 \(b\) 之前,最终 \(a\) 在 \(b\) 之后,就对于 \(a,b\) 之间需要一次交换,类似逆序对。将所有 \(a,b\) 求和,就是需要的至少的交换次数。这个是一个经典的结论,可以通过归纳,在 \(a\) 序列中找到 \(b_1\) 的位置,移到 \(b_1\),说明这是可以达到的。
4. Bulbasaur
考虑建图:\(2n-2\) 列,第 \(2t,2t+1\) 列横着连 \(k\) 条容量为 \(+\infty\),第 \(2t-1,2t\) 列的容量是 \(1\)。求从源点到汇点的最大流。
等于最小割。那么只会割容量是 \(1\) 的边。设 \(dp_{l,r,S}\) 表示源点和集合 \(S\) 中的点联通的情况下需要割掉的最小的边数。固定 \(r,S\) dp 关于 \(l\) 单调递增,且 \(0\le dp_{l,r,S}\le k\)。
改设 \(f_{r,S,x}\) 表示最大的 \(l\) 使得 \(dp_{l,r,S}\le x\)。\(f\) 仍然具有单调性。相当于利用值域很小的性质砍掉了一个 \(n\) 变成了 \(k\)。
5. 4/9 模拟赛
T1
容斥一些边相等,容斥系数为 \((-1)^e\)。
设 \(f_n\) 表示一个大小为 \(n\) 的连通块的容斥系数,经典结论 \(f_n=(-1)^{n-1}(n-1)!\)。
子集 exp 可以做到 \(O(n^22^n)\)。
两两不同 -> 连通块容斥 / 扫描值域。连通块容斥不一定要是贝尔数的,甚至不一定是 \(3^n\),可以是 \(2^nn^2\)。
T2
设权值最小的四元组 \((a_0,b_0,c_0,d_0)\)。
如果查询 \(a\ne a_0,b\ne b_0,c\ne c_0,d\ne d_0\),那么答案就是 \((a_0,b_0,c_0,d_0)\)。否则存在 \(a=a_0\),\(b=b_0\),\(c=c_0\) 或 \(d=d_0\)。那么这是 \(4\) 个 \(3\) 维的子问题。
先往支配集中加入 \((a_0,b_0,c_0,d_0)\),接着枚举 \(a=a_0\),\(b=b_0\),\(c=c_0\) 或 \(d=d_0\),并上 \(a_t\ne a_0\) 的三元组 \((b_t,c_t,d_t)\) 的支配集。
显然这个支配集覆盖了所有可能的询问,因此任意一个询问的答案必定属于这个支配集。
设 \(T(d)=dT(d-1)+1,T(0)=1\),解得 \(T(4)=65\)。对 \(n\) 个元素建树,如果直接实现,复杂度为 \(O(T(d)n)\)。考虑每一层,把点集划分为若干个集合,考虑如果集合之间有交,则可以将其中一个调整成无交,因为一个元素如果属于支配集,也就是说可以成为某次询问的答案,也一定属于任意一个集合的支配集。因此复杂度为 \(O(nd^2)\)(\(d\) 层,每层访问 \(n\) 个元素每个一遍,每次访问遍历 \(d\) 个维度每个一次)。在树上做查询,复杂度为 \(O(d^2)\)(\(d\) 层,每层比较是 \(O(d)\) 的)。注意到修改和询问不平衡,因此考虑定期重构。设块长为 \(B\),注意每次重构时会有 \(B+T(d)\) 个元素。复杂度为单次 \(O(\frac{(B+T(d))d^2}B+d^2)\)。取个几何均值得到 \(O(\sqrt{T(d)}d^2)\)。带入 \(T(d)=O(d!)\),得到 \(O(\sqrt{d!}d^2)\)。
对于可离线的情况,使用容斥,在 \(2^d\) 个线段树上二分,复杂度 \(O(2^d\log n)\)。
T3
对于随机排列,笛卡尔树树高期望是 \(O(\log n)\)。
学了一下好写的线性建笛卡尔树。
考虑分块,处理所有 \(l\) 落在某个整块的询问。类似回滚莫对地,扫描 \(r\),加入 \(r\) 记录块外的答案是好做的。还需要考虑 \(l\) 对答案的影响。可以看作一个三元组 \((L,R,ans)\),从 \(x\) 走到 \(t\),\(L,R\) 表示给向左、向右的贡献,\(ans\) 表示累积的答案,每一步根据是向左还是向右更新 dp 值,也就是乘上一个矩阵。也就是需要求出一段路径上矩阵的积,差分一下变成一段逆矩阵的积和一段积。也可以看作是先走到根,再倒着走回 \(t\),这样也很容易设计逆矩阵。
关键思想:将答案扩展为一个矩阵,树上前缀积、前缀逆的积,分块。
6. Double X
调整法。
考虑一张二分图 \(G\),问题变为求 \(G\) 的大小为 \(4\) 的最大匹配。
对于每个左部点,只保留连出去的边权前 \(4\) 小,这样边数变为 \(4n\)。同理,对于每个右部点也只留前 \(4\) 小。这样每个点度数不超过 \(4\)。对于所有缩减留下的边,只保留边权前 \(25\) 小。
考虑调整法。如果最优解一个点的连边不是前 \(4\) 小,考虑前 \(4\) 小的出边中,一定有一条的出点是没有被选的。调整为这条边不劣。
如果最优解一条边不是前 \(25\) 小,考虑选中的其他 \(6\) 个点,最多占用 \(24\) 条边,因此前 \(25\) 小的边中总有一条边可以调整。
更紧的界可以到 \(22\)。上述证明的问题在于可能有多条不在支配集的边,那么每条边就会占用 \(8\) 条支配集中的边。考虑取出所有不在支配集的边进行调整,假设有两条不在支配集。那么剩下的边每条最多占用 \(7\) 条支配集中边,总共 \(14\) 条。剩余 \(8\) 条,任取一条不在支配集的边,只会额外占 \(7\) 条,那么总是可以剩下最后一条边。
7. 外环路
边分治流程:首先将树三度化。对于二叉树,一定存在一条边,使得两边点数落在 \([n/3,2n/3]\) 内。断开割边将树划分为两个连通块,继续递归,那么递归深度为 \(\log_{3/2}n\)。
设割边为 \((U,V)\),子树内两侧的叶子为 \(L,R\)。对于所有跨出子树的路径,必然经过 \(U,L,R\) 中一个,因此分别从 \(U,L,R\) 开始处理出最短路,更新询问的答案。之后每个询问的路径一定在两个子树内部,因此对两个连通块分治。时间复杂度 \(O(n\log^2 n+q\log n)\)。
8. [SNOI2024] 拉丁方
考虑 \(C=n\)。考虑左部点为 \(n\) 种数,右部点为 \(n\) 列。每一列都有一个需要填补的颜色集合。每个点的度数恰好为 \(n-R\),因此一定存在 \(n-R\) 染色。这种情况只需要满足初始矩阵合法,就一定有解。
那么问题转化为填入 \(R\) 行 \(n-C\) 列,使得子矩阵合法。
考虑还是左部点为 \(n\) 种数,右部点为 \(R\) 行,那么右部点度数为 \(n-C\)。如果某个数度数大于 \(n-C\) 那么无解,否则一定可以将图补全,变成左右均 \(n\) 个点,\(n-C\) 度的正则图。将左边缺失的度数用右边 \(n-R\) 个点轮流弥补。
换言之,左部点度数为 \(d\),右部点度数不超过 \(d\) 的二分图存在完美匹配。左右度数都不超过 \(d\) 的二分图存在 \(d\)-边染色。
最后需要求解一个二分图边染色。使用 dinic 跑 \(n\) 次二分图匹配的复杂度为 \(n^3\sqrt n\),使用二分图边染色复杂度为 \(O(n^3)\),使用随机化方法可以 \(O(n^2\log n)\)。
9. [NOI2023] 字符串
完全不会做。
这样一个正反字典序的条件,很难用什么结构去维护。
从条件的角度上去思考,尝试对条件容斥。将条件放成前缀后缀的字典序关系 \(S_l<P_r\)。但这样会算重,因此需要斥掉 \([l,r]\) 构成回文串,且 \(S_l<P_r\)。但是这样就有三个变量 \(l,r,p\),\(p\) 是回文串的中心,不用 PAM 等结构不可做。消掉 \(p\) 困难,因此考虑消掉 \(l,r\),条件等价于 \(S_{p+1}<P_p\)。这样 \(p\) 对 \(l\) 是一个一维的限制,\(l\) 对 \(p\) 也是一个一维的限制,\(r\) 成功被消除了。是一个二维偏序的形式。
思想:将子串的字典序条件放缩为前后缀;结构与条件的理解;类二维偏序;容斥原理在数据结构数点上的应用。
需要加深的知识点:manacher 单独处理奇/偶回文串不用二倍的写法;对双关键字计数排序的理解 “四步”:清空cnt数组、累计cnt、对cnt做前缀和、按照第二关键字从劣到优的顺序依次把每个点排在答案数组的cnt对应位置。
一种特殊的二维偏序问题的分步贡献法:
比如说\(x\)是询问给定的常数,需要统计有多少\(y\),满足\(L_x\le y\le R_x,P_y\le x\le Q_y\)。一种理解是二元组\((x,P_x),(Q_y,y)\)之间的二维偏序。
也可以看作是\(y\)能贡献到的\(x\)是一个范围,\(x\)能接受的\(y\)是一个范围,扫描\(x\),那么可以在\(x\)进入\(y\)的范围的时刻加入,挂在\(y\)的位置上;\(x\)走出\(y\)的范围的时候,将\(y\)删除。处理挂到\(x\)上的查询,查询在\(x\)范围内的\(y\)的信息和。
10. 字符串
我们考虑将所有长度为 \(k\) 的子串插入到一个 trie 里,如果我们已经得到了这个 trie 的虚树,那么我们在虚树上贪心即可。
那么如何得到这个虚树?这就是 \(ab\) 拼接的后缀树。
11. Cool Slogans
直接建出 \(s\) 的 SAM。条件等价于选出一个子串最大化 border 个数。这个很难在 SAM 上体现,因此考虑放成选择一系列字符串,它们的右端点相同,且每一个都在上一个中出现了至少两次。这样的一些字符串显然在 SAM 上构成一个链。可以从上到下贪心,判断一个串是否可以接在我之后,用可持久化线段树维护 endpos 集合。
证明:对于每个 endpos 等价类,只需要考虑最长的串。即,如果 \(y,x\) 能接上,\(z\) 和 \(y\) 属于同一个等价类,\(|z|>|y|\),那么 \(z,x\) 也行。
对于 \(x\) 的每一次出现,找到 \(y\) 在 \(x\) 中的出现位置,\(z\) 一定向左跨出了 \(x\),产生一个更长的串 \(t\)。因为 \(x\) 每次出现 \(t\) 都出现,所以 \(t\) 属于 \(x\) 或 \(x\) 的祖先,所以 \(|t|\le |x|\),与 \(|t|>|x|\) 矛盾。
上面两道题用的了两种思考方式,一个是假设法,即逆推,一个是顺推。
12. [NOI2018] 你的名字
对 \(S\) 建立 SAM。对 \(T\) 的每个前缀,设 \(f_i\) 表示最长的后缀的长度,在 \(S[l,r]\) 中出现了。则有单调性 \(f_i\le f_{i-1}+1\),即 \(f_i-i\le f_{i-1}-(i-1)\),可以使用双指针求出 \(f_i\) 以及 \(f_i\) 在 \(S\) 的 SAM 的对应结点。那么其实就是求有多少个点在某条到根的路径上被覆盖了,也就是所有结点在 \(S\) 的 parent 树上的虚树大小,拆成 dfn 相邻的 lca(注意这里是点权,所以要把点权拆到边上,以及注意要去掉非叶子)。
不能只想纵向的单调性,还有横向的单调性!!!!
13. CF1098F Ж-function
先上个 SA 把串拍成序列。
对序列分治,设 \(A_i\) 表示 \(i\) 到分治中心的高度最小值。则一个点 \(i\) 对另一侧的一个询问 \(l,r\) 的贡献为 \(\min(A_i,A_l,r+1-i)\)。直接三维数点的复杂度为 \(O(n\log^3 n)\)。
将 \((i,A_i)\) 画在二维平面上,如图。

找到 \(y=A_l\) 和 \(x+y=r+1\) 的交点 \(P\)。以 \(P\) 为界,左右都是一个形如一个横坐标区间内的 \(A_i\) 和一条直线取 \(\min\) 的形式,是一个二维数点。时间复杂度 \(O(n\log^2 n)\)。
思想:将信息视作平面上的点,限制视作半平面。
14. Alphabetic Tree
将所有串以 $ 为分割符连接为一个整串 \(S\)。对于一个询问的串 \(T\),即统计,有多少 \(S\) 的后缀 \(S'\) 满足 \(S'\) 是 \(T\) 的前缀。发现这样等价于 \(T\le S'\le T+\infty\)。所以满足条件的 \(S'\) 是一段区间,二分出这一段区间,再做一个二维数点即可。
那么考虑如何比较 \(S'\) 和 \(T\) 的大小关系。使用 heavy-light decomposition 将树上的路径分解为若干段区间。哈希依次判断 \(T\) 的一段区间是否不等于 \(S'\) 的对应区间,如果是,就在内部继续二分下去。
总的复杂度为 \(O(n\log^2 n)\)。
思想:是一个串的前缀的串是 SA 数组上的一段区间。
15. AND = OR
设 AND \(=\) OR \(=x\),按 popcount 对所有数分类。显然所有 popcount \(<x\) 的都只能分到 \(S\),\(>x\) 的都只能分到 \(T\),\(=x\) 的都只能是 \(x\)。思想:将特征信息压缩。
16. Bring Balance
找到折线最高点 \(p\),翻转 \([0,p],[p,2n]\)。翻转一个区间可以看作是折线图上关于中心点做中心对称,或旋转 180 度,或先上下翻折,再左右翻折。因为一开始所有点都在 \([-\infty,h_p]\) 间,上下翻折后依然在 \([0,+\infty]\)。
因此 \(ans\le 2\), 只需要判断答案能否 \(\le 1\)。判断答案是 \(1\),可以先找到横轴下方的区域,扩成一段区间,再贪心找到区间左右的最高点进行翻转。
17. Cat Cut
能得到的串为一个 \(S_k\) 的子串(其中 \(k\ge 2\))或 \(S_1\) 的后缀,拼接上 \(S_{k+1...n}\) 的依次的一段前缀。
朴素的 dp 需要设二维的状态 \(dp_{i,j}\) 表示后 \(i\) 个一共选了总长度为 \(j\)。但是注意到,设 \(T=dp_{i,m}\),则每个 \(dp_{i,j}\) 都是 \(T\) 的一段长度为 \(j\) 的前缀。因为,整个的字典序最优的串 \(T\) 一定在每个前缀都是最优的。
稍加转化,我们需要解决的是,给定两个串 \(S,T\) 求最小的 \(S[1,k]T\)。或,给定两个串 \(S,T\) 求最小的 \(S[l,r]T\),要求线性。
先解决第一个,考虑如何比较两个 \(k\),那么在求出 Z 函数后可以 \(O(1)\) 比较。
考虑第二个问题,找到 \(S'=S+\infty\) 的最小后缀,那么一定取在了 \(S'\) 的前缀,使用最小表示法可以线性。
补充:Z 函数的思想和 manacher 类似,代码也极为相似。最小表示法本身是求字典序最小的后缀,思想还是考虑比较两个后缀,并排除一些不可能成为答案的后缀,如果要求最小 cyclic shift 那么可以转化为求 \(S^2+\infty\) 的最小后缀,取前 \(n\) 个。(\(+\infty\) 是因为要保证不能是 \(n+1...2n\) 开始的后缀)
18. Partition AND/OR Aggregation
\(r\to r+1\),分数变小。当 \(l=r\) 时,分数取到最大值 \(1\)。
第一问,最大化 \(M\) 段中的第 \(K\) 大。若 \(K<M\),则分成 \(M-1\) 个 \(1\) 和一个 \(N-M+1\),答案可以取到最大值 \(1\)。否则 \(K=M\),即最大化最小值,二分。
第二问,最小化 \(M\) 段中的第 \(K\) 大,即先分成 \(M\) 段,再从中选出 \(M+1-K\) 段,最小化其中的最大值。枚举选择的 \(K\) 段,设总长度为 \(L\),那么首先 \(N-L\ge M-K\)。并且在满足这个条件的基础上一定可以分出另外的 \(M\) 段,只需要单个元素分一组,如果有多余,那么将原本选择的段变长只会更小。二分答案 \(X\),求选出 \(K\) 段,每段 \(\le X\),最小化总长度。
设 \(ans_j\) 表示分成 \(j\) 段的答案,则 \(ans_j\le ans_{j+1}\),且 \(ans\) 下凸。那么 wqs 二分即可。内层 dp 是线性的,外加外层的二分答案,总的是 2log。
补充:
这种 dp 似乎并不是标准的 \(dp_{i,j}=\min dp_{k,j-1}+w(j+1,i)\) 的形式,如果是这种形式那么我们只需要说明 \(w\) 是蒙日的,那么根据定理 \(dp_i\) 关于 \(j\) 就自然凸。那么如何证明本题的 dp 是凸的呢?
本题的区别就在于选出来的这些段不一定是相连的。考虑等价于选出相连的 \(K\) 段,每一段的分数是其中最短的合法子段。只需说明新的 \(w\) 呈现蒙日就可以了。根据定义 \(w\) 是蒙日的当且仅当 \(w(l,r)\) 满足四边形不等式。
定义 \(w(l,r)\) 表示 \([l,r]\) 内的最短的合法子段,如果不存在,定义 \(w(l,r)=\infty^{n-(r-l)}\)。
考虑四个端点 \(abcd\)。如果 \(bc\) 段无解,那么因为定义的比较规则,\(\infty^{n-(c-b)}\) 已经大于 \(ac,bd\)(就算都无解),所以四边形不等式满足。
否则 \(bc\) 段合法,考虑 \(ad\) 段最短子段一定不会包含 \(bc\) 段的最短子段,分讨发现任意一种方案总是对应 \(ac-bd\) 段的一组方案,所以 \(ac-bd\) 不劣于 \(ad-bc\),四边形不等式满足。
因为 \(w\) 是蒙日的,任意一个蒙日矩阵的 \(k\) 次幂每一项关于 \(k\) 凸。
补充2:
本题中需要对一个分数二分。对分数二分有以下几种思路:
- 直接使用实数二分,得到一个近似解,再根据近似解重跑一遍得到答案分数。常数大 (\(\log{\frac1{\epsilon}}\)),且精度差。
- 如果可能的答案不多,可以先得到所有可能的答案分数列表,在列表中二分。如在本题中,可能的答案只有 \(O(n\log V)\) 种。
- 使用 Stern-Brocot Tree。
补充3:
蒙日矩阵是什么?
从定义出发,满足四边形不等式的矩阵叫做蒙日矩阵。
一个简单的判定:蒙日矩阵是二维差分非负/非正的矩阵。
对于 \(x,x+1,y,y+1\),四边形不等式成立,\(A_{x,y}+A_{x+1,y+1}\le A_{x,y+1}+A_{x+1,y}\)。变形得到 \(A'_{x,y}=A_{x,y}+A_{x-1,y-1}-A_{x-1,y}-A_{x,y-1}\le 0\)。
19. Tree Growing
如果要计算所有点对的树上距离之和,一种常见的方法是拆每条边的贡献。
考虑仍然沿用拆边的思路,设 \(f(a,b,k)\) 表示一条连接左右各 \(a,b\) 个点的边,还有 \(k\) 个待插入点,这条边的贡献是多少。
分三种情况:插到左边一条边,插到右边一条边,插到这条边。
有递推 \(f(a,b,k)=\frac a{a+b-1}f(a+1,b,k-1)+\frac b{a+b-1}f(a,b+1,k-1)\);
\(f(a,b,0)=ab\)。
展开,枚举最后 \(a\) 加了 \(i\),\(b\) 加了 \(k-i\),方案数为一个格路方案数,分母就是 \((a+b+k-2)^{\underline k}\),分子就是 \(C(k,i)a^ib^{k-i}ab\)。
总结:弥补之前的缺漏,像这种走 \(k\) 步,每步要么 \(a+1\),要么 \(b+1\),概率是以 \(a+b\) 为分母的 \(a,b\) 为分子的什么东西,都是可以很简单的计算的,并且最终的式子推出来是一个优美的三次下降幂。不要被之前的自己误导了,以为没法做。 区别与直接力大砖飞拆贡献,可以先得到一个递推式,再根据递推式求通项。好处是能得到简洁的式子,难点是考验组合式代数推导的水平。推组合式子的基本方法:从阶乘中拆出组合数、再使用范德蒙德上下指标卷积。或者组合意义。
20. Grid L
设长方形边长为 \(a,b\),不妨假设 \(1\le a\le b\)。则根据总边数,\(p+2q=a(b+1)+(a+1)b\)。即 \((2a+1)(2b+1)=2p+4q+1\)。
证明:覆盖一个 \(a\times b\) 的矩形至少需要 \(|a-b|\) 个 “——” 型的木棍。
首先,\(|a-b|\) 个总是可以达到的,可以由一个正方形拼接一个长方形得到,而正方形存在完美覆盖,根据对角线对半分开即可。

其次,竖边横边各有 \(n(m+1),(n+1)m\) 个,每个 “L” 形木棒会使用横竖各一个,因此至少有 \(|n(m+1)-(n+1)m|=|n-m|\) 条边没有覆盖。
\((2a+1)^2\le (2a+1)(2b+1)=2p+4q+1\),因此 \(2a+1\) 枚举到根号即可。
21. 4月14日 模拟赛题
A
操作一二相当于前后缀差分,操作三相当于求前缀和。差分数组的前缀和等于原数组,因此可以将区间和倒退到上一次操作前的单点值。
考虑点对点的贡献,是一个 \(F_2\) 的组合数,根据卢卡斯定理等价于二进制位互相包含。因此可以 \(O(B)\) 计算单点求值。对于每次重构,不妨取 \(\bm {B=2^k}\),每次只会贡献到两个位置,这部分可以 \(O(n)\)。因此复杂度为 \(O(n\sqrt n)\)。
对于后缀差分,考虑整体换元,发现就是往开头结尾稍作调整。
C
考虑所有联通图中的非广义串并联图。缩到无法再缩时,残余的一定是一个胚图 \(G\)。\(G\) 每个点度数都至少是 \(3\)。先算出 \(G\) 的方案数。
再考虑通过胚图反向生成原图。胚图的每一个点,都可以挂着若干个广义串并联图;胚图的每一条边,都可以是一个广义串并联图缩点后的结果。算出点/边的生成函数 \(A(x,y),B(x,y)\),最后求的形如 \(\sum G_{i,j}A^i(x,y)B^j(x,y)\),即 \(G(A(x,y),B(x,y))\)。
22. Speckled Band
首先判掉 \(S\) 不包含出现两次的字符,这种情况一定无解。
否则答案不超过 \(4\)。
- \(ans\le 1\)。\(S\) 一定形如 \(AAAA...\),即 \(S=A^k\)。
- \(ans\le 2\)。设两种串分别是 \(A,B\),如果 \(S\) 包含的 \(AB\) 段数 \(\ge 4\),一定满足 \(S=A...A\) 或 \(B...B\) 或 \(AA...\) 或 \(...BB\) 或 \(AB...AB\),一定可以重新划分,使段数更短。因此只需要判断 \(S\) 是否形如 \(AAB\) 或 \(ABA\) 或 \(BAA\)。
- \(ans\le 3\)。如果 \(S_1\) 或 \(S_n\) 再串中出现了至少两次,那么一定可以。否则 \(S_1,S_n\) 所在的段一定不能作为出现两次的段,这种情况下 \(S\) 一定形如 \(BAAC\)。
判 \(AAB,BAA,BAAC\),只需要预处理从每个位置开始/结束的最短 AA 串。判 \(ABA\) 也就是判是否有 \(\le n/2\) 的 border,根据经典结论有 \(<n\) 的 border 等价于有 \(\le n/2\) 的 border,因此相当于看一个子串是否存在 border。判 \(S=A^k\) 相当于看是否存在整周期,\(O(d(n))\) 是极其简单的,其他不会。
23. Grid Coloring 3
考虑初始局面必然存在一个同色的十字。删掉同色的十字后,每次就可以删任意同色的行或列。
设 \(f_{n,m}\) 表示有多少 \(n\) 行 \(m\) 列的矩阵可以通过删除同色行列删空。
考虑一次性删去所有能删的行或列,那么有三种情况:
- 只存在同色行
- 只存在同色列
- 存在同色十字,那么所有十字应该是同色的
先把前两种情况给容斥掉,设同色行数为 \(c\),也就是 \(c\ne 0\),经典 \([c\ne 0]=\sum_{i=1}^c \binom{c}i(-1)^{i-1}\),枚举 \(i\) 行/ \(j\) 列同色,容斥系数 \((-1)^{i-1}\)。
那么对于第三种情况,设有 \(r\) 行 \(c\) 列同色,不妨假设 \(r<n,c<m\)。那么首先会在前面被算 \(+2\) 次。手推一下前几项,发现是正负交替的,表格的左上角是 \(-1\),即 \((-1)^{r+c-1}\)。
对于 \(r=n,c=m\) 需要特殊处理。稍加计算,被算入答案的次数为 \(2-\left(\sum_{i=1}^{n-1}(-1)^i\binom{n}{i}\right)\left(\sum_{j=1}^{m-1}\binom{m}{j}(-1)^j\right)=2-4[2\nmid n,m]\)。因此额外加上 \((4[2\nmid n,m]-1)V\)。同理,对于最后的项,计算得 \((1-4[2\nmid n,m])V\)。
24. Герої та Монстри
考虑判定:对于集合中的 \(k\) 个人去匹配前 \(k\) 个怪,集合外的 \(n-k\) 个人匹配后 \(n-k\) 个怪。
枚举 \(k\)。因为只关心能不能打过的一个大小关系,找到 \(b_k\) 的位置切开,右边的人一定能打过左边的怪物,左边的人一定打不过右边的怪物,因此前缀后缀分别 \(O(n^2)\) dp,再 \(O(n^2)\) 合并前后缀。
25. DFS Order 4
26. 4月16日 模拟赛题
A
枚举前缀,计算不合法的概率。设有 \(a\) 张牌出现了 \(3\) 次及以上,\(b\) 张牌出现了 \(2\) 次,那么即 \(a\le 3\) 或 \(a+b\le 4\)。即 \(a\le 3\) 或 \(a=4,b=0\),分别计算方案数。
考虑先选出属于这个前缀的牌的集合,再乘上 \(p!(4n-p)!\) 给其重排。例如,\(a\le 3\) 的生成函数为 \((1+4x+6x^2)^{n-a}(4x^3+x^4)^a\)。枚举 \(a\),对于后面的项暴力展开,对于前面,使用 p-recursive 线性解出所有的系数。
p-recursive:
欲求 \(P^n\)。
\((P^n)'=nP^{n-1}P'\)
\((P^n)'P=nP^nP'\)
两边同时提取 \(x^k\) 项系数,
得到递推式:
\(\sum_{i=0}^m (k+1-i)a_{k+1-i}b_i=n\sum_{i=1}^m b_iia_{k+1-i}\)。
整理,
\((k+1)a_{k+1}b_0=\sum_{i=1}^m a_{k+1-i}b_i((n+1)i-k-1)\)
\(a_{k+1}=\frac1{(k+1)b_0}\sum_{i=1}^m a_{k+1-i}b_i((n+1)i-k-1)\)
B
原路返回相当于根本没走。
考虑 \(0\) 的位置是不重要的,逆时针标号 \(1...2n-1\),看成一个环排列,一次操作即选择一个长度为 \(n\) 的区间循环移位。
C
缩减图。
27. DFS Order 4
考虑贪心判定,加入一个数前先不断弹栈,直到能加为止,贪心地作为一个新的儿子接在栈顶之后。
对贪心可以得到的树进行计数,即:
- 每个点的儿子单调
- 父亲小于第一个儿子
- 前一个儿子的最后一个儿子大于后一个儿子
对条件 \(3\) 容斥,条件 \(1,3\) 总有恰好一个保留,结构是“链状”的,因此 dp 需要记录附加在我的最后一个儿子之后的子树大小。
做法 \(1\)
\((i,x,0)\) 表示有一个大小为 \(x\) 的东西接在我的最后一个儿子上,如果没有最后一个儿子,就接在我自己身上;
\((i,x,1)\) 表示有一个大小为 \(x\) 的东西接在我的最后一个儿子的最后一个儿子上,如果没有最后一个儿子,就接在我自己身上。转移枚举最后一个儿子的大小 \(a\)。
做法 \(2\)
\((i,x)\) 表示有一个大小为 \(x\) 的子树接在我的最后一个儿子上,但是转移时不再枚举最后一个儿子,而是改为枚举第一个儿子。
28. 前线支援
\(dist(u,v)=dep_u+dep_v-2dep_{lca(u,v)}\)。
如果 \(y\) 不在 \(x\) 的子树内那么会对 \(x\) 子树内的每个点 \(u\) 贡献 \(dep_u+dep_y-2dep_t\)。线段树维护 \(\sum dep_u\) 以及 \(\sum a_u,\sum b_udep_u\)。
否则,如果 \(y\) 在 \(x\) 的子树内,那么首先贡献 \(dep_u+dep_y\),将 \(dep_{lca(u,y)}\) 拆在 \(y\) 到 \(x\) 的每一条边上,对于其中一条边 \(z\),将 \(c_z-=2\),一个点到根的 \(\sum c_z\) 即这个点的答案。
查询是 \(x\) 子树内所有点到根的 \(\sum c_z\) 之和。拆为两部分分别统计,对从 \(x\) 到根之间的 \(z\) 贡献为 \(c_zsz_x\),对于 \(x\) 子树内的 \(z\) 贡献为 \(c_zsz_z\)。
时间复杂度 \(O(q\log^2 n)\) 或 \(O(q\log n)\)(使用全局平衡二叉树)。
29. Construction of Highway
做法 1
树剖,再使用颜色段均摊的分析,得到一个结论:每次一个点到根的所有颜色等价类均摊是 \(O(N\log N)\) 的。
直接树剖,配合 set 找出等价类是 \(O(N\log^2 N)\) 的。
考虑定位到的路径一定是一段前缀,因此使用栈替代 set,找等价类复杂度降为 \(O(N\log N)\)。
做法 2
考虑这实际上就是 LCT 的 access 操作。
每次,执行 \(access(x)\) 将 \(x\) 到根的链打通,并将记录路径上每条 splay 的颜色,最后将整条 splay 颜色设为 \(c\)。颜色段的数量不会超过 LCT 的均摊复杂度 \(O(N\log N)\)。
实现时,一条 splay 的颜色可以统一打在根处,\(splay(x)\) 或 \(access(x)\) 中断重边时都要对根标记的颜色进行下传。
虽然 LCT 做法年寻址不算连续但是常数比树剖更优秀。
这两种做法找颜色段的复杂度都是 1log,当然这个题找到等价类之后还要数逆序对,所以最后都是 2log。
30. 水池
半群信息设计。
简单来说,有信息 \(D\) 和标记 \(O\) 两个集合。
定义在信息和信息之间的运算 \(+\),满足结合律,但不一定满足交换律;定义在标记和标记之间的运算 \(\times\),满足结合律,但不一定满足交换律;定义在信息和标记之间的运算 \(\times\),结果是一个信息,满足分配律。
如果标记满足交换律,就可以标记永久化。
带有下传懒标记的动态开点线段树空间分析:
对于单点修改,会产生一条毛毛虫,pushdown 新建的点是毛毛虫的足,因此每次修改使用的空间不超过 \(2\log V\)。对于区间修改,产生的结构形如两条毛毛虫,因此空间消耗为 \(4\log V\)。
对于区间查询操作,如果不通过精细实现,仍会有结点被新建,空间消耗仍然是 \(4\log V\)。
如果像这道题一样还需要可持久化,空间不变,为 \(2\log n\) 或 \(4\log n\)。
31. 成都七中
点分治做法
将询问分为两类:包含分治中心的询问、不包含分治中心的询问。对于不含分治中心的询问,递归到子树求解。对于包含分治中心的询问,可以令 \(x\) 为分治中心。
对于一个点,可以求出一个 \([l_i,r_i]\),表示这个点能保留当且仅当 \([l_i,r_i]\subseteq [L,R]\)。那么实际上是询问子区间颜色数。
数颜色数的方法:1. 将等价类标在代表元上 2. 对每种颜色的点集独立考虑
扫描左端点。使用第一种方法,为每种颜色维护一个代表元,表示这种颜色出现最早的右端点,在扫描线中的变化量是 \(O(1)\) 的,可以直接维护。时间复杂度 \(O(n\log^2 n+q\log n)\)。
总结:区间颜色数、区间子区间颜色数、树上直上直下的路径颜色数,都可以做。
树上路径颜色数无法低于根号。考虑 \(\sqrt n\) 条 \(\sqrt n\) 长度的链,询问两条链的颜色数就可以得到这两条链的点积,规约 \(\sqrt n\times \sqrt n\) 大小的 01 矩乘。
重构树做法
32. 4月21日 模拟赛
策略有大问题,一直以为自己会了 t2 正解(实际上不仅难写很多还带 log),时间也很充裕,结果到了最后半小时才调出来 \(O(n^3)\),还被卡常了,想尽了各种办法拿到那 8 分,却没发现前面我 \(n^3\) 能过的分基本都是送的特殊性质分,还导致 t3 暴力分也没时间写了,甚至题都没时间看。
A
考虑一个 \(n\times m\) 的网格,横竖都有连边,还有一些小按奇偶分布的 \(2\times 2\) 正方形要求四个点颜色都不同。
不妨假设 \(n\le m\),对轮廓线状压,记录每个格子的状态,其中相邻两个格子一定不能同时选,状态数为 \(fib_n\),即 \(1.618^n\),复杂度 \(O(1.618^n nm)\)。
考虑对于 \(n/2\) 个 \(2\times 2\) 的小正方形,只需要记录这里面有没有点,所以状态数实际只有 \(O(2^{n/2}nm)=O(1.414^n nm)\)。
B
对于第一问,根据卡莱公式,方案数为 \(n^{k-2}\prod a_i\)。先断成一些连通块,再在每个连通块内选一个点贡献 \(n\)。因此第一问表面上只能 \(O(n^2)\),实际上可以 \(O(n)\)。
对于第二问,称 \(1\) 到 \(n\) 的路径经过的块为关键块,那么选出关键块,再为每个关键块指定一个入点和出点(可以是同一个点),在某一对入点和出点之间指定一条边(也可以是新加的边),最后乘上 \(c!\)。记录 \(c\),子树包含根的块是否包含 \(n\),是否选定了入/出点,是否选出了一条边,是否选出了一个点贡献到答案里面,是否选出了关键块内的一个点算入答案(所有关键块总共只需要选出一个点)。在连通块根处决定父边是否割掉,如果选择割掉,再决定这个块是否作为关键块,最后把子树清零,更新全局的信息。
写法学习:把状态压到一个二进制数里(这个题是 \(2^6\) 种),而不是直接写 dp[a][b][c][d][e][f],一方面写代码更省力,另一方面也方便状态转移(这个题只需要对两个二进制数做一个不交并,而如果直接写需要写六重循环),方便压缩无用的状态和无用的转移(这个题只需要跑一遍大样例,把非零的状态和转移打个表记录下来)。
写法学习:树形 dp,既可以在加入一个儿子的时候决定是否断开连边,也可以在处理完一个点的后立即决定是否断开父边,后者在转移较为复杂的时候会非常方便,避免了同一个处有大量的分讨,独立的决策过程独立进行。

浙公网安备 33010602011771号