2022.03 学习记录
03.01
[「NOI2013」向量内积]
先考虑 \(k=2\)。我们不能枚举任两个向量进行判断。考虑 \(m\) 个向量与某个向量 \(u\) 的 \(\bmod k\) 意义下内积和,如果都不合法则应为 \(m\),因此若内积和 \(s\not\equiv m\pmod{k}\),则 \(m\) 个向量中一定存在一个与 \(u\) 合法。\(O(d)\) 维护前缀内积和,为防止出题人卡可以随机打乱顺序。
\(k=3\) 时,注意到 \(1^2\equiv2^2\equiv 1\pmod{3}\),因此只需要维护内积平方和,\(O(d^2)\) 。
这告诉我们乱搞的思想还是很重要的。
[AGC016F] Games on DAG
见寒假的学习笔记 02.05
。
P4229 某位歌姬的故事
经典 trick:把区间拆成左闭右开使得每段的贡献形式一样(也即不存在区间开头是左/右端点的区别)。
离散化,每个点代表其后一段左闭右开的区间。以下均用点表示其代表的区间,而区间代表输入的限制区间。对于每个点,我们求出其能达到的最大值。显然限制相同的区间可以放在一起处理,设当且限制为 \(x\),此时我们只需要把那些最大值为 \(x\) 的点单独拿出来处理即可。问题转化为:若干点,若干区间,每个区间中至少选一个数的方案数。设 \(f_{i,j}\) 表示前 \(i\) 个点,最后一个选的点为 \(j\)。对每个点,预处理 \(p_i\) 表示在它之前选点,至少应该选到哪个位置。转移时分在不在 \(i\) 选点,有:
其中 \(w_1(i)\) 为选 \(i\) 的方案数,\(w_2(i)\) 为不选 \(i\) 的方案数。
剩下一些不被任何区间覆盖的点拿出来特判,可以任意取值。
还有一点是判断无解,只需判断区间中是否存在对应需取到最大值的点即可。
dp 题最好想清楚对象、方程再写。
P4929 【模板】舞蹈链(DLX)
同时作为 DLX 的一些建模的初步总结。
主要思想:使用十字链表进行行列的删除,强剪枝。复杂度只与 \(1\) 的个数有关。
精确覆盖:每次选 \(1\) 最少的列删除。
重复覆盖:不能直接删除所选的列,剪枝力度小了很多,使用 IDA* 优化。
建模:每一行代表一个可选变量,每一列代表一个需满足的限制。这一行中为 \(1\) 的位置代表选该变量能满足该限制。视题目要求转化为精确/重复覆盖。
例:数独。把每个格子(恰好要有一个数)、每行、每列、每个小宫格都看作一列,每个格子是否填了某个苏看作一行。精确覆盖。
例:破坏正方形。每行代表一条边,每列为一个未破坏正方形,行上为 \(1\) 的点对应其能破坏的正方形。重复覆盖。
注意点:DLX 开数组空间时,要注意给行首留空间。
03.02
[10618. 「2021-10-14 提高模拟赛」挑选子序列 (sequence)]
答案显然有单调性,二分答案。发现 \(t\) 中一个字符能分别覆盖到 \(s_1,s_2\) 中的一些位置,而我们的目标是选出 \(m\) 个位置使得 \(s_1,s_2\) 能被完全覆盖。重复覆盖问题。
CF700E Cool Slogans
见寒假的学习笔记 02.08
。
CF1037H Security
最优解显然可以贪心:先尽可能和询问串重合,然后填一个尽可能小的字符。倒着枚举重合长度,再枚举新加的字符,我们需要判断一个结点是否有 endpos 存在于一个区间中,线段树合并判断。
P3702 [SDOI2017]序列计数
补集转化:总数减去不包含质数的方案数。考虑总数,记 \(c_i = \sum [j\equiv i\pmod{p}]\),则对 \(C\) 做循环卷积快速幂即可。不含质数同理。
至少包含一个/至少有一个包含 通常使用补集转化来简化问题。
[「2021 省队集训 day5」搭积木 (block)]
\(容积 = 总量 - 容器体积\)。容器体积就是 \(\sum h_i\),我们只需要求出总量。把所有积木按高度降序排序,先放最高的积木。剩下的每个积木的在放置时有两种选择,要么加到最左边成为新的容器的壁(贡献为自己的高度),要么加到当且容器壁的右边(贡献为容器壁的高度)。那么对于一块积木 \(i\),每一块高度小等于它的积木都可以以 \(h_i\) 为贡献。设 \(f_{i,j}\) 表示用了 \(i\) 块积木,总量为 \(j\) 是否能达到。 转移时从小到大枚举高度,如果当前高度有积木即可转移,类似完全背包,bitset 优化。
[AGC047C] Product Modulo
记 \(c_i=\sum[a_j=i]\),则答案为 \(\sum\limits_{i}\sum\limits_{j}c_ic_j(ij\bmod P)\)。取 \(P\) 的原根 \(g=2\),同时将 \(c_i\) 含义相应转化,即求 \(\sum\limits_{i}\sum\limits_{j}c_ic_jg^{(i+j\bmod P)}\),FFT 预处理 \(c\) 的自卷即可。
在面对乘法取模的卷积时,原根是很值得思考的一个方向。
[「2021 省队集训 day2」所有子串 LCS (alcs)]
神仙论文题,并没有完全理解。大致思路利用 dp 的转移图分析问题,设 \(f_i(j,k)\) 从 \((0,i)\) 到 \((j,k)\) 的最大价值,然后发掘性质,发现一个转移的分界点,然后递推这个分界点。
[「2021 省队集训 day3」选拔赛 (game)]
由于已按照值排序,所以我们选的一定是最大值和一段前缀,可以通过调整法证明。显然答案是关于前缀长度的凸函数,三分,但这超出询问次数,甚至斜率二分也不行。事实上斜率二分本质上也是三分,只不过询问点为 \(mid\) 和 \(mid+1\)。我们想要尽可能利用三分得到的信息,考虑能否构造询问使得下一次能利用上一次询问得到的信息,设出两次区间长度,解方程得到 \(\dfrac{\sqrt 5-1}{2}\),非常优美。按照这个数字设置三分询问点即可有效减少询问次数。
[「2021 省队集训 day3」树 (tree)]
口胡。
显然需要对问题做一些转化,最好能规约到某个模型。首先可以有一些粗略的思考:连通块的数量大致是什么级别?大致和什么东西是同级别的?这几乎不能思考出答案,但可能有些启发。对于树上不强制选根的统计/最优化,我们往往使用点分治转化为强制选根的情况。而对于强制选根的连通块问题情况,我们往往按照 dfs 序考虑问题。更多内容可以参见国集 2018 论文《解决树上连通块问题的一些技巧和工具》。
对于这道题,点分治完了之后,把所有点按点分子树 dfs 序排序,连边 \(p_i \to p_{i+1}\),边权 \(a_{p_i}\);\(p_i \to p_{i+siz_{i}}\),边权 \(0\);特别地,最后一个点连向超级汇点,超级源点连向点分子树的根。我们发现,从源点到汇点的一条路径和树上连通块构成双射,于是问题转化为建出的新图上的 k 短路。
简单回顾一下 k 短路。建出反图以 \(T\) 为根的最短路径树。考虑一条从 \(S\) 到 \(T\) 的路径,如果其非树边集合确定,那么其长度也就确定了。设非树边集合为 \(P\),则 \(P\) 由若干连续路径段组成,且两个路径段的起点和终点在最短路径树上是祖先关系。而向集合中加入一条非树边,增加的长度也是确定且容易计算的。因此我们可以通过替换与增量非树边构造出所有路径。因此对每个点,维护其最短路径树祖先链上连出的所有非树边权值,需要支持查询最小值,使用堆维护;又因为需要支持与父亲信息的合并,使用可持久化可并堆。
03.04
[「2020-09-20 联考」哈希 (hash)]
数位 dp,前缀和相减,从高到底考虑,\(f_{i,j,0/1}\) 表示从高到低前 \(i\) 位,当前数位和为 \(j\) 的答案,这里运用类似贡献提前计算的思想,转移时考虑新加一位的贡献。\(f_{i,j} = \sum\limits_{k=0}^{d}f_{i-1,k}+10^{i-1}k\cdot s\),其中 \(s\) 表示考虑完 \(i\) 以下的位后的 \(S()\) 的和,再开一个 dp 数组 \(g\) 维护 \(s\) 即可。
[#10306. 「2019-12-05 提高模拟赛」国家队选拔 (money)]
从底至顶考虑。考虑维护子树中的权值,我们需要比对当前子树根与子树中最大权值的关系。最好的情况自然是子树根不需要改变,否则我们有两种思路:
- 改子树根
- 改子树中所有权值大于子树根的点
注意到在继续考虑祖先的过程中,此前做出的决策可能需要改变。因此可以有一个类似反悔贪心的思路:当子树根小于子树中最大值时,我们可以用子树根“对掉”子树中的最大值,对应到实际操作中就是把子树根改为最大值;但是随着继续考虑祖先,我们会在某个时间点将此前的决策全部推翻,即把子树最大值改为原子树根。但我们发现,决策的改变并不影响答案。因此我们只需要多维护一个反悔操作——在子树的权值中加入用来“对掉”最大值的子树根权值即可。使用 multiset
启发式合并或可并堆维护。
P5289 [十二省联考 2019] 皮配
之前做的题,补个题解。
考虑没有不喜欢的导师的情况,划分阵营和划分战队是独立的,分别背包求,最后乘起来。考虑把存在不喜欢导师的学生单独考虑,剩下照常做之前的背包。对于存在不喜欢导师的学校,我们需要对其所属的城市一起考虑。设 \(f_{i,j}\) 表示该学校加入蓝阵营,蓝阵营有 \(i\) 个人,鸭派系 \(j\) 个人的方案数,\(g_{i,j}\) 表示该学校加入红阵营,其余和 \(f\) 一致。分每座城市 ban 的是哪个导师转移。
最后枚举存在不喜欢导师的学校中,蓝阵营多少人,红阵营多少人即可合并背包求出答案。
[六省联考 2017] 寿司餐厅
之前做的题,补个题解。
对每种代号的寿司建点,对每种综合收益组合建点,则我们有如下限制:
- 选 \(d_{i,j}\),则必须选 \(d_{i+1,j}\) 和 \(d_{i,j-1}\)
- 选 \(d_{i,i}\),则必须选 \(a_i\) 和 \(m\cdot a_i^2\),后者只能选一次,因此要多建一个点。
这转化为一个最大权闭合子图模型。
[六省联考 2017] 期末考试
之前做的题,补个题解。
算法 1
直接枚举最晚公布成绩的时间,拆一下式子,预处理一下各种前缀和、后缀和,分 \(A\gt B\) 和 \(A\gt B\) 分别考虑就能 \(O(1)\) 计算。
算法 2
答案关于最晚时间是单谷函数,很好感性理解。把枚举改成三分。
[八省联考 2018] 劈配
之前做的题,补个题解。
魔改匈牙利为当前点能否匹配某等级志愿,顺便维护匹配了哪个导师,按排名从高到低枚举,按志愿从高到低枚举,即可求出第一问答案。对于第二问,如果能被满意的志愿录取就没问题;否则匹配过程中顺便求出被替换的人能到达的小于其本身排名的最大排名即可。
匈牙利是一个很灵活的算法,匹配过程可以各种魔改。
03.05
写总结。
03.06
联合省选的题单独开一篇文章写。
[「2022-03-06 联考」 百日誓师 (queue)]
求一定存在于 LIS 中的下标。(不是求方案数)
排列的性质很好,判断一个下标是否能存在于 LIS 中很容易,只需正着求 LIS 和倒着求 LDS。必要性需要判断:
- 是否所有 LIS 为 \(k\) 的 \(i\) 都能存在于 LIS 中
- LIS 为 \(k\) 的数是否唯一
[「2022-03-06 联考」 聚餐 (dine)]
设 \(f_{u,i}\) 表示考虑以 \(u\) 为根的子树,\(u\) 填 \(i\) 的方案数。\(f_{u,i} = \prod\limits_{v\in son_u}\sum\limits_{(i,j)=1}f_{v,j}\),用 \(\mu\) 展开后狄利克雷前缀和转移。记录前后缀积换根即可。
[「2022-03-06 联考」早餐店 (breakfast)]
考虑合法区间 \([x,y]\) 需要满足什么性质。记 \(a\) 为括号序列的前缀和,显然有 \(a_{x-1}=a_{y}=\min\limits_{x\le i\le y} a_i\)。对于一次询问 \([l,r]\),求出区间中最左和最右的最小值位置记为 \(x,y\),则 \([x,y]\) 必为合法区间。注意到 \([l,x)\) 和 \((y,r]\) 中所有数都大于 \(a_x\),所以直接求区间中每个数往右/左延伸的其作为最小值的控制区间即可,单调栈预处理。所有值都是区间最值,ST 表。
CF1630D Flipping Range
操作的单位区间是 \(l=\gcd\{b\}\),也即所有操作都可转化为对一段长度为 \(l\) 的区间操作。进一步,我们可以将两个下标相隔 \(l\) 的位置同时取反。那么把所有下标按照 \(i\bmod l\) 分组,每组中最多保留一个负数。具体来说,若组中负数个数为偶数,则可全部取反;否则剩一个。
但我们可以选择最开始将任意一段长度为 \(l\) 的区间取反使得所有组中负数的奇偶性改变。因此还需考虑将奇偶性讨论反着做的答案。
03.07
P3822 [NOI2017] 整数
线段树做法比较显然,所以我想了一个压位 set
做法。
首先我们知道,二进制加法器暴力加一的均摊复杂度为 \(O(1)\)。由此如果只有加法,我们暴力做即可。可以压几位用 unsigned long long
储存。现在还要减法,这无疑破坏了均摊的性质。因此我们将加法和减法分开维护。对于查询,此时需要考虑退位的问题。我们只需要知道从 \(k\) 往前第一个不一样的位置,用 set
维护加法与减法值不一样的块,找到 \(k\) 所在块之前第一个不一样的即可。
调试问题:unsigned int
右移 \(32\) 位是 ub。
03.08
CF1637E Best Pair
本质不同的 \(c_x\) 只有 \(\sqrt n\) 种,枚举一个数 \(x\),枚举 \(c_y\le c_x\),每次尽可能用 \(c_y\) 中最大的去匹配 \(x\),匹配到了就跳出。不合法的匹配只有 \(O(m)\) 种。
CF1638E Colorful Operations
口胡。
修改的时候给对应颜色打上标记,染色的时候下放标记。注意每次染色增加 \(O(1)\) 段区间,因此总区间个数 \(O(m)\) 级别,使用 set
什么的维护区间,树状数组维护区间加即可。
[#8062. 一双木棋 (chess)]
算法 1
两人落子的形状形如一个阶梯,可达状态数在 \(O(\dbinom{n+m}{m})\),直接上 min-max 搜索加记忆化。
算法 2
轮廓线 dp。将轮廓线上格子的边的横竖计入状态,可以转移到增加一格格子,也即将两个相邻的边横竖取反。由于转移图比较乱,使用记忆化搜索。
03.09
集合幂级数的东西单独写一篇文章。
P4364 [九省联考 2018] IIIDX
见寒假的学习笔记 02.08
。
P4365 [九省联考 2018] 秘密袭击 coat
转化为求对每个 \(i\) 求权值 \(\ge i\) 的点数量为 \(k\) 的连通块数量。有暴力 dp \(f_{u,i,j}\) 表示 \(u\) 为根的子树中 \(\ge i\) 的点有 \(j\) 个的连通块数,这里钦定根必选。把状态看成 GF 的形式,设 \(F_{u,i}(x)\)。则有 \(F_{u,i} = a_u\prod\limits_{v\in son_u}(F_{v,i}+1)\),其中 \(a_u\) 表示 \(u\) 对形式幂指数的贡献(\(x\) 或 \(1\))。为了方便统计答案,再设 \(G_{u,i}(x)\) 表示子树内系数的和,即 \(G_{u,i}=F_{u,i}+\sum G_{v,i}\)。出题人有病要写 MTT 还过不去。既然系数不好做,我们考虑点值。多项式的点值性质非常好,比如乘法就是对应系数相乘。因此我们维护点值序列,最后再插值回去。在最外层枚举点值,剩下一个二维 dp;将第二维看作线段树下标,需要支持:
- 全局赋 \(1\)
- 区间乘法
- 合并子树,即对应项分别相乘、相加
- 区间 \(+1\)
- 把 \(g\) 加上 \(f\)
维护变换四元组 \((a,b,c,d)\),其中 \(b,d\) 分指状态的 \(F,G\)。构造运算 \((a_1,b_1,c_1,d_1)\cdot (a_2,b_2,c_2,d_2) = (a_1a_2,b_1a_2+b_2,c_1+a_1c_2,d_1+d_2+b_1c_2)\),这个运算满足结合律,且容易验证正确性。
线段树合并维护 dp 后插值即可。
关于线段树合并时的区间修改,可以通过整体打标记,下传标记的时候新建子结点实现。
03.10
P4384 [八省联考 2018] 制胡窜
补集转化,求出切两刀不存在询问串的方案数。假设我们知道 \(s\) 中询问串出现的所有位置,则可以分类讨论:
- 存在三个不相交的询问串
- 存在一个位置能干烂所有询问串
- 至少需要两刀才能干烂所有询问串
设 \(s\) 中询问串出现的所有位置为 \([l_i,r_i]\),则这些情况对答案的贡献中不能 \(O(1)\) 计算的都形如 \(\sum\limits _{x\le r_{i+1}\le y}(r_{i+1}-r_i)(r_{i+1}-p)\),\(p\) 为常数。建出 SAM 后可以使用倍增找到询问串对应结点,线段树合并维护 endpos 集合并顺带维护维护上式,设所有询问串中第一个和最后一个为 \([l_1,r_1]\) 和 \([l_k,r_k]\),通过 \(r_1\) 与 \(l_k\) 间的关系即可判断属于上面哪种情况。
计算贡献的时候要时刻考虑去重。字符串的问题最好多画图来理清串串间的关系。
调试问题:倍增的时候从儿子开始枚举。
CF341E Candies Game
分析一次操作。设有 \(a_x\le a_y\),则一次操作后 \(a_x\) 会乘二,这让我们想到了倍增。如果能让 \(a_x\) 一直倍增下去,就能使 \(a_y\) 变成 \(a_y\bmod a_x\) 了!为此,我们需要一个 \(a_z \ge a_y\) 来辅助操作:将 \(\dfrac{a_y}{a_x}\) 二进制分解即可构造。由欧几里得算法的过程可知,总操作次数是 \(O(n\log n\log a)\) 的。
03.11
[「2022-03-16 省选模拟赛」林间漫步 (wander)]
二分答案,有暴力 dp \(f_{u,i,j}\) 表示 \(u\) 子树中,到第一个叶子路径长度为 \(i\),最后一个叶子到根路径长度为 \(j\),是否合法。枚举两个儿子的两条路径匹配转移。最后如果 \(f_1\) 存在合法的即可。
先写了一个暴力,然后因为空间太大过不去样例 2。于是开始思考如何优化空间。注意到有用的状态数似乎很少,仔细分析,发现只有满足 \(i\) 递增 \(j\) 递减的下标才是有用的。因此对每个结点维护二元组集合 \(f=\{(x,y)\}\) 表示合法状态,转移的时候双指针找到满足的即可。注意需要满足第二维的单调性。
挂分原因:vector
为空的时候没有判。要时刻检查边界情况。
[「2022-03-16 省选模拟赛」序列划分 (divide)]
显然有暴力 dp \(f_i = \sum f_j \operatorname{mex}(j+1,i)\)。我们只需要维护后缀的 \(\operatorname{mex}\) 即可,它显然被分成若干段连续的不增序列。加入一个数时 \(x\) 时,只有原先 \(\operatorname{mex}=x\) 的位置贡献会发生改变,对每种 \(\operatorname{mex}\) 维护其所控制的区间,总改变量是 \(O(n)\) 的。我们还需支持查询一个位置对应的 \(\operatorname{mex}\),这可以用一棵以值为下标的线段树维护每个值最后出现的位置的最小值,在其上二分即可。
[「2022-03-16 省选模拟赛」重排列 (permutation)]
假设 Alice 重新排列之后得到序列 \(B\),考虑 Bob 会怎么操作。对于不互质的数对 \((B_i,B_j)\)(\(i\lt j\))Bob 是不能改动的,其在答案序列中的相对顺序应该与 \(B\) 中一致。因此对不互质数对 \((B_i,B_j)\)(\(i\lt j\))连边 \(i\to j\) 表示 \(i\) 在 \(j\) 前,求出最大字典序拓扑排序即可。
那么我们能不能直接求出 \(B\) 呢?还是考虑不互质数对 \((A_i,A_j)\)(\(A_i\lt A_j\)),由于 Alice 想让字典序最小,她肯定想让小的在前面。一种直接的想法是对所有不互质数对 \((A_i,A_j)\)(\(A_i\lt A_j\))连边 \(i\to j\),但这很容易构造数据卡掉,比如 \(A=\{2,3,6\}\),原因在于 \(3\) 应该受到 \(2\) 的制约。推广一下,所有弱连通块中的点都应该受到其中权值最小点的约束,由于还要保证无环,我们可以对其构造以最小权值点为根的 dfs 树,连边按照自根至底的顺序。这个过程也可以看作给无向边定向。
时间复杂度 \(\mathcal{O}(n^2\log A)\)。
03.12
写总结。
[#8962. 概率论 (prob)]
二叉树个数显然是卡特兰数,设为 \(F(x)=\dfrac{1-\sqrt{1-4x}}{2x}\),\(f_n = \dfrac{1}{n+1}\dbinom{2n}{n}\)。设所有二叉树叶节点数量总和为 \(g_n = 2\sum\limits_{i=0}^{n-1}g_if_{n-1-i}\),写成 GF 的形式,需要注意 \(g_0=0,g_1=1\),因此这两位拿出来单独考虑,有 \(G(x) = 2xF(x)G(x)+x\),带入 \(F(x)\) 则有 \(G(x)=\dfrac{x}{\sqrt{1-4x}}\)。注意到二者共有 \(\sqrt{1-4x}\) 而且指数上只差 \(1\),这很求导。构造发现 \((xF(x))^{\prime} = \dfrac{G(x)}x\),可得 \(g_n = nf_{n-1}\)。带入卡特兰数通项即可计算。
P4859 已经没有什么好害怕的了
恰好
显然是二项式反演。先排序,设 \(f_{i,j}\) 表示前 \(i\) 个,\(a\gt b\) 的有 \(j\) 个。预处理每个 \(a_i\) 能匹配多少 \(b_j\) 即可。
03.13
[「2022-03-13 联考」糖果之战 (candies)]
显然能否取该糖果只与先后手的能量差是否大于 \(0\) 有关。显然的 dp 以能量值为状态,但是太大了;但是 dp 的值很小,因此考虑值和状态互换。然后发现正着比较难做,我们倒着做:\(f_{i,j}\) 表示考虑 \(i\sim n\) 的糖果,先手美味值总和为 \(j\) 时,先后手的能量差的最小值(即 差值在 \([f_{i,j},f_{i,j+1})\) 的能量都只能拿 \(j\) 的美味值)。转移考虑取不取当前石子:
-
不取,\(f_{i,j} \gets \max(1,f_{i+1,j}+r_i+1)\)
-
取,此时交换先后手,\(f_{i,j}\gets -(f_{i+1,suf_{i}-j+1}+r_i-1)\),注意这里括号内取的是可行范围的最大值。
最后找一个最大的美味值使其 \(\ge a-b\),即初始差值即可。
考场上没有想到倒过来做。
[「2022-03-13 联考」爱跑步的小孩 (children)]
等价于要求所有环长度相同。每个点双显然独立,其要么是大环,要么恰好中两个度数 \(\gt 2\) 的结点,且其度数相同,并要求这两点间所有路径长度相同。判断环长是否相同和统计方案数是容易的。
[「2022-03-13 联考」头盔 (helmet)]
用你喜欢的数据结构维护即可。CDQ、树套树、分块均可过。
「POI2011 R1」KON-Conspiracy
求把图分成一个团和一个独立集的方案数。
- \(n\le 10^6\)
高明性质题。
性质 1:两种方案中,两个点不可能同时存在于团和独立集中。
证明显然。这就意味着,假如我们有一个划分方案,其它的所有方案和它最多相差一个点(可以是增加、减少、替换)。
性质 2:团一定由度数最大的几个点构成。
可以使用反证法。
结合这两个性质,我们考虑一个增量构造:把点按照度数排序,枚举选几个(设为 \(k\)),使其恰好合法。如果我们可以确定一个方案合法,那么剩下的无非是:用同度数的点替换,或增加一个度数为 \(k\) 的点。
问题在于如何判断一个点集合法。这只需满足 \(团中结点度数和=团中边数+总边数\) 即可。
03.14
[「2022-03-14 省选模拟赛」矩阵基问题 (basis)]
向量的线性无关组显然可以增量构造。设 \(f_{i,j}\) 表示有 \(i\) 个向量,基大小为 \(j\) 的方案数。转移系数可以写成一个上三角矩阵,这自然联想到特征多项式(因为其特征多项式是好求的)。所以我们真的用特征多项式去求通项即可。
[「2022-03-14 省选模拟赛」超市门口的游戏机 (marbles)]
考虑计算 \(f(n,m)\)。枚举向左走几步,得到一个 \(O(n)\) 的式子,它可以一项一项递推,预处理前缀和做完第一问。
对于二三问,观察式子,发现类似卷积形式,对应 GF 也是容易构造的。把暴力的答案式子展开,发现与生成函数的展开形式一致,直接将 \(p_2,q_2\) 之类的代入 \(x\) 做完。
03.15
[ 「2022-03-15 省选模拟赛」构造大师 (master)]
先考虑顺序恢复,需要在不改变已恢复的数的情况下把当前数归位。稍微构造一下感觉很像魔方,于是我们用拼魔方的思想做就好了。
[「2022-03-15 省选模拟赛」猜数游戏 (number)]
先考虑 \(op=1\)。一个提示 \(y\) 能接在 \(x\) 的第 \(i\) 位后,当且仅当:\(y\) 在集合意义下是 \(x\) 的子集,且 \(x\) 在第 \(i\) 位后是 \(y\) 的子序列。所以 \(y\) 能匹配 \(x\) 的一个后缀,预处理能匹配的最前的位置。设 \(f_{s,i,l}\) 表示考虑了集合 \(s\) 中的提示,当前在考虑提示 \(i\),匹配到其第 \(l\) 位。转移考虑下一个提示或新增一位。
\(op=2\) 时,新增状态处理向左的提示:\(f_{s,i,l,j,r}\) 表示考虑了集合 \(s\) 中的提示,当前在向左考虑提示 \(i\),从后往前匹配到其第 \(l\) 位,向右考虑提示 \(j\),从前往后匹配到第 \(r\) 位。转移还是考虑下一个提示或新增一位。
为了处理停止匹配向左/开始匹配向右,可以新增空提示 \(n\) 来占位。
[「2022-03-15 省选模拟赛」稻草人 (scarecrow)]
曼哈顿转切比雪夫(或者拆绝对值分类讨论)之后,则新加入一个点后,能产生贡献的只有 \(x,y\) 正负四个方向的最值。分别维护四个方向的最值点对,和全局最优 \((u,v)\),不含 \(u\) 的,不含 \(v\) 的。
03.16
#4228. 「2019-10-23 名校联考」消失的序列 (stack)
可以把入栈与出栈对应左右括号,于是如果没有第 \(p\) 项的限制,答案是卡特兰数第 \(n\) 项。我们考虑枚举第 \(p\) 个左括号在括号序列中的位置,则可算出 \(p\) 前的左右括号数量,\(x\) 后的左右括号数量,\(p,x\) 之间则是一段匹配的括号序。于是三段都是合法括号序的形式,用拓展卡特兰数 \(Cat(n,m) = \dbinom{n+m}{m}-\dbinom{n+m}{m-1}\) 计算即可。
#379. 「2021 省队集训 day6」消失的序列・改 (stacktwo)
和上一题一样的背景,却有完全不一样的思考方式。
考虑一个序列合法的条件,即 \(\not \exist i\lt j\lt k,a_k\lt a_i\lt a_j\)。可以证明这是充要的。对于字典序大等于某序列的问题,一般性的思路是枚举相同的前缀,再枚举下一个数填一个比原序列大的数,后面任意。这题我们同样这么考虑,假设已经确定排列的前 \(i-1\) 位,第 \(i\) 能填什么?前 \(i-1\) 位会把新序列的值域分割成若干段,而第 \(i\) 位只能在第一段填数,否则不满足上述条件。那么这样剩下的数就可以放到任意一个位置上。我们考虑在一段中填数的方案数,列出递推式,发现和卡特兰数是一致的!所以我们直接按照一般性的思路,枚举当前数填在第一段的哪个位置上,即有 \(O(n^2)\) 做法,瓶颈在于求 \(\sum\limits_{i=0}^{x}Cat(i)Cat(l-i)\)。但由于卡特兰数性质非常好,这个式子也可以由递推式改写成 \(Cat(l+1)- \sum\limits_{i=0}^{l-x}Cat(i)Cat(l-i)\)。这样我们的复杂度和启发式分裂一样了。
#4166. 「2020-06-07 联考」三原色 (color)
不强制选根的连通块计数,点分治后每个点分子树按 dfs 背包 dp。
#4242. 「2020-11-15 联考」爱与和平 (peace)
题意应当是一个数的所有孩子互质。可能能证明这和深度等价,但我不会。考虑钦定树边从大指向小形成内向树(\(1\) 除外),\(f_{i,0/1}\) 表示 \(i\) 为根子树中,选/不选 \(i\) 的独立集大小。注意到一个数的不可重质因子个数少得离谱,并且注意到分成二叉树一定是不劣的,因此我们可以大力枚举其不可重质因子的集合,转移即为合并两个集合。为了方便我们用质因子的最高幂次代表选这个质因子,所以每个数要贡献到其倍数。最后加上 \(1\) 的贡献即可。
03.17
[「2022-03-16 省选模拟赛」交通 (traffic)]
考虑一次行走的过程,当遇到红灯时,会等到绿灯;而此时等价于从第 \(0\) 秒开始。因此如果能对每个点处理出 \(s_i\) 表示第 \(0\) 秒从 \(i\) 出发到终点的时间,就只需要求第一个遇到红灯的点。然后你发现求 \(s_i\) 应该从后往前递推,也要求第一个遇到红灯的点。将时间对 \(r+g\) 取模后,维护每段区间最早被哪个点覆盖,可以使用动态开点线段树。
[「2022-03-16 省选模拟赛」选拔 (selection)]
把所有字符串拼在一起,用分隔符隔开,放到树上统一匹配。设 \(f_{u,i},g_{u,i}\) 表示从 \(u\) 子树中到 \(u\) 从前往后匹配了 \(i\) 位,从从 \(u\) 子树中到 \(u\) 从后往前匹配了 \(i\) 位(注意这里是若干串的匹配位置的集合)。转移和合并答案是容易的,bitset
优化。注意要把 dfs 序离下来转移,否则栈空间会炸。
[ 「2022-03-16 省选模拟赛」等待 (wait)]
先想一个暴力:枚举位数,假设更高位已填好,如果当前位填 \(0\),以下全部填 \(1\) 是否满足题设。对于每个数,维护其当前最高位的 \(1\) 的位置集合(记为 \(c_i\)),从高到低枚举位数,有这么几种情况:
- 当前位填 \(0\),则 \(\{c\}\) 中不能存在大于当前位。
- 当前位填 \(1\),记 \(\{c\}\) 中有 \(t\) 个数等于当前位。
- \(t=0\),则贪心地使用最大的 \(c\) 满足这一位;
- \(t=1\),则用恰好相等的那个 \(c\) 满足这一位,并将其下一位加入集合;
- \(t\gt 1\),则非法。
有一个观察:设当前数降序排序后的最高位序列为 \(\{l\}\),则 \(最高位\in [\max\{l_i+i-1\},\max\{l_i+i\}]\)。由此可以省去枚举位数的过程。接下来需要优化的是填数的过程。找到集合中第一个 \(j\) 满足 \(l_j+j-1 = \max\{l_i+i-1\}\),则 \(j\) 之前的数一定属于情况 2.3
,可以直接去掉。由此执行一个递归的过程,使用线段树维护集合 \(\{c\}\),在递归的每层找到最小的 \(j\),把其前的全部删去,讨论最高位是多少。可以证明复杂度是正确的。
实现上,线段树有一些比较高妙的处理方式。最开始每个数减去 INF
表示没被选过,被选上就加上 INF
,可以有效减少维护难度。
03.18
[ 「2022-03-18 省选模拟赛」不知道 (unknow) ]
树剖线段树套李超树 \(O(n\log^3n)\)。实际上大多数询问都是重链的一段前缀,可以把询问离线下来逐个加入;剩下的 \(O(m)\) 个询问挂到线段树上做,合并的时候李超树合并就都是 \(\log^2n\) 的了。
[ 「2022-03-18 省选模拟赛」任凭风浪起,稳坐钓鱼台 (xor) ]
有 \(O(\dfrac{n^2k}{\omega})\) 的暴力,也可以枚举三个二进制考虑其贡献做到 \(O(nk^3)\)。用这个平衡复杂度就能被卡常。正确姿势是我们需要给 \(O(nk^3)\) 与处理一下,除一个 \(8\).
[ 「2022-03-18 省选模拟赛」灯笼 (lanterns) ]
喵。
03.19
学习 min-max 容斥,挑了一些题做,详见学习笔记。
03.20
[「2022-03-20 联考」省选选拔 (selection)]
卡精度题。答案显然为
当 \(2a_i\le x\) 时,泰勒展开后只需要 \(20\) 项左右即可达到精度要求;否则,我们考虑暴力乘。那么有一个分治的思路:考虑当前区间中最大值,判断其与 \(x\) 的关系。分治过程中加一个当前答案精度的判断。注意到 \(x\gt a_i\),我们把所有数都除掉 \(\max a_i\) 就不需要高精度了。
[「2022-03-20 联考」神秘数据 (data)]
如果我们有两张图,则可以通过用一条边把它们连起来,得到一张生成树个数为两图乘积的新图。随机 \(1000\) 张 \(12\) 个点的新图,每个询问选 \(4\) 张图拼起来,无解概率很低。选四张图的情况,我们把选两张图的生成树个数 hash 一下即可。
[「2022-03-20 联考」学校杀 (kill)]
分类讨论的模拟题,小根堆维护每个学校进队人、省队,大根堆维护每个学校没进队人、还有名额的学校的没进队的最大值,大力分类讨论。
03.21
[「2022-03-21 省选模拟赛」速通 (isaac)]
假设我们知道重开时间为 \(t\),设 \(f_{u,i}\) 表示 \(u\) 子树中,这局还剩 \(i\) 的时间,总共用时。枚举在 \(u\) 花了多少时间,如果 \(j\ge i\) 就直接转移,否则花费 \(j\) 的时间后重开。直觉上来看这个重开时间可以三分;实际上设重开时间为 \(x\),总时间为 \(g(x)\),我们的目标是不重开,即 \(g(x)=x\),容易证明零点是唯一的。因此直接二分。
[「2022-03-21 省选模拟赛」虚数之树 (regression)]
点分树板子题。
[「2022-03-21 省选模拟赛」叮叮车 (dingdingcar)]
\(f(n) = Cat(n) = \dfrac {1}{n+1}\dbinom{2n}n\),所以所求即为 \(\max v_p(\binom{2n}n)\)。
库默尔定理:\(\dbinom{n+m}n\) 中 \(d\) 的幂次为 \(n+m\) 在 \(d\) 进制下的加法进位次数。
这个定理不是必须的,只是为了方便考虑。现在我们只需要找到 \(n\) 使得 \(2n\) 在 \(7\) 进制下进位数最多。以下默认按 \(7\) 进制描述一个数。直观来看,我们希望 \(6\) 的个数越多越好,但这个可能不满足值域限制。枚举维护 \(x\),在其之下都填 \(6\),其上与 \(r\) 保持一致,第 \(x\) 位填 \(r-1\)。贡献是容易计算的:维护连续的 \(\gt 3\) 的段长度和连续 \(3\) 的长度即可。
[SNOI2019]通信
暴力网络流建图比较显然,建图时序列上每个点需要向前面所有点连边,这个过程需要优化。比较暴力的做法是线段树,但是有点大材小用。我们可以分治:对每个分治区间建一排点,表示权值的递增序列,然后后半区间向对应权值代表的点连边,对应权值代表的点向前半区间连边。
上下界网络流
上下界可行流
一张图,每条有流量上下界 \([l,r]\),求一种可行方案使每个点流量平衡。
先强制为每条边流满下界的流量,但是这样流量不一定平衡。容易想到建立超级源汇 \(S,T\) 补齐流量。具体的,\(S\) 向流量大于 \(0\) 的结点连边,流量小于 \(0\) 的结点向 \(T\) 连边,若 \(S\) 到 \(T\) 的最大流恰好等于所需补齐的流量(即满流),则存在可行流;否则不存在。据此也容易构造每条边的流量。
上下界最大流
一张图,每条有流量上下界 \([l,r]\),给定源汇 \(s,t\),求最大流。
同样的,先强制为每条边流满下界的流量,但此时原图中源汇流量不平衡,不能直接像上一个问题那样。为了解决这个问题,我们强制让它流量平衡:从 \(t\) 到 \(s\) 连容量正无穷的边就平衡了。接下来先要判断是否存在可行流,若存在,我们在残量网络上跑 \(s\) 到 \(t\) 的最大流即可。
上下界最小流
一张图,每条有流量上下界 \([l,r]\),给定源汇 \(s,t\),求最小流。
建图和最大流是一样的。求出可行流之后,此时 \(s\) 到 \(t\) 的流量就是 \(t\to s\) 边的流量,减去从 \(t\) 到 \(s\) 的最大流即可。
03.22
[「2022-03-22 省选模拟赛」小 F 与游戏 (game)]
B 序列合法当且仅当:
- 前 \(k-1\) 位由不超过两个递减序列组成,且大于两数列最后一项的数在前缀中全部出现;
- 第 \(k\) 位为 \(1\);
- 后 \(n-k-1\) 位在双端队列中单调(方案数为 \(2^{\max(n-k-1,1)}\))
对前 \(k-1\) 位 dp,设 \(f_{i,j}\) 表示填了 \(i\) 个数,已填数的最小值为 \(j\)(作为其中一个递减序列的结尾)。则转移时上一位要么比 \(j\) 大,要么填到另一个另一个序列后,只有一种方案。即 \(f_{i,j} = \sum\limits_{k\ge j} f_{i-1,k}\)。
注意 \(i\gt n-j+1\),即已填数字大于可选数字的情况是非法的。
写成后缀和的形式 \(f_{i,j} = f_{i-1,j} + f_{i,j+1}\)。令 \(g_{i,j} = f_{i,n-j}\),则 \(g_{i,j} = g_{i-1,j} + g_{i,j-1}\),合法条件是 \(j\ge i\),这相当于从 \((1,1)\) 走到 \((n,k)\) 不越过直线 \(y=x\) 的方案数,用类似卡特兰数的方法算即可。
[「2022-03-22 省选模拟赛」小 Z 与函数 (function)]
不考虑 \(vs\),考虑每个元素的贡献,等价于求序列去重之后的顺序对个数。
\(vs\) 相当于一个元素后面是否存在比它大的元素,不妨对一个元素考虑前面是否有元素可以替换它。注意到每次替换之后,每个会被考虑的位置上的元素是不降的,因此我们直接用最开始序列考虑即可,那么不会产生贡献就等价于其为前缀最小值。加入一个数 \(x\) 的时候,在它前面且小于 \(x\) 并大于前缀最小值的数都会产生贡献,用栈维护不会产生贡献的数的去重集即可。
[ 「2022-03-22 省选模拟赛」小 W 与骑士 (knight)]
分类讨论:
-
\(A,B\) 平行,则判掉一堆边界之后,对某一个维度 dp 即可,枚举每轮每次加上哪个向量即可。无穷解:要么能走到 \([-500,500]\) 外,要么成环,可以用走的次数大于 \(1000\) 判断。
-
\(A,B\) 不平行,则判掉不合法之后,转化为每次使 \(x\) 或 \(y\) 增加 \(1\),不能经过一些点的平面行走方案数,有经典的组合意义容斥 dp。
03.23
[「2022-03-23 省选模拟赛」子集和计数问题 (sum)]
部分分做法:\(m\le n+1\)
把所有元素减去 \(1\),这和原问题是等价的。
引理:对于可行价值和 \(y\),所有可行 \(x\) 构成一个区间。
证明参考出题人题解。
于是我们可以用价值和为体积做 01 背包。注意到大小不同的物品只有 \(\sqrt n\) 种,合并一下做多重背包即可。
[「2022-03-23 省选模拟赛」最优子序列问题 (sequence)]
即求 \((m-1)\sum a_{b_i} - \sum\limits_{i\ne j} \min\{a_{b_i}\dots a_{b_j}\}\),建出笛卡尔树后在其上 dp 即可。
[「2022-03-23 省选模拟赛」自动手记人偶 (violet)]
先考虑 \(n\) 为偶数,先不考虑首尾的限制,对于 \(\forall i=2k+1\),此时有 \(a_i \le m-1-a_{i+1}\)(记为基本条件
)和 \(m-1-a_{i+1}\ge a_{i+2}\)(记为限制
)。我们在满足基本条件的情况下,对限制进行容斥。设 \(f_{j}\) 表示钦定 \(j\) 个 \(\ge\) 不满足的方案数,容斥系数即为 \((-1)^j\),那么剩下的 $\ge $ 把原序列划分乘 \(\dfrac{n}2-j\) 段形如 \(a_1\le a_2\lt a_3\le a_4\cdots\lt a_{2k-1}\le a_{2k}\) 的链,这样一段的方案数即为 \(\dbinom{m+k}{2k}\),设其 OGF 为 \(F(x)\),则一个 \(j\) 的方案数即为 \([x^{\frac{n}2}]F^{\frac{n}2-j}\)。现在考虑 \(a_1\le m-1-a_{n}\),设此时 \(a_1\) 所在的段长度为 \(2k\),则链头可以有 \(k\) 种选择方法,所以方案数应该是 \([x^{\frac{n}2-1}]F^{\prime}F^{\frac{n}2-j-1}\)。因此答案为:
然后考虑 \(n\) 为奇数。此时不能直接套用上述方法。我们需要再分析一些性质。记 \(\ge \lceil \dfrac{m}2\rceil\) 的数为大数,其余为小数,则不存在大数与大数相邻的情况。注意到小数之间互不影响,则可以将环从小数间切开,切成若干段长度为奇数的链。问题转化为 \(m\gets \lfloor\dfrac{m}2\rfloor\) 的问题,长度为奇数的链的 OGF 可以用和偶数一样的方法推导。注意有一个情况是 \(m\) 为奇数的时候会出现 \(a_{i}=\lfloor\dfrac{m}2\rfloor\) 的情况,但此时它只能是单独一个,给系数加上 \(x^0\) 即可。剩下还有亿些推导,但是并不关键,参考热心题解。
03.24
[「2022-03-24 省选模拟赛」异或矩阵 (matrix)]
赛时手玩找到规律,实际上有更加科学的方法。
考虑 \(j\) 对 \(f_{m,i}\) 的贡献次数为 \(\dbinom{m-1}{j-i}\),由于运算是异或,因此组合数为奇数时才有贡献,即 \((m-1)\and (j-i)=(j-i)\),即 \((m-1-j+i)\and (j-i)=0\)。那我们只需要在 \(m-1\) 在二进制下为 \(1\) 的位下转移 dp 即可。
变式
一棵树,每一轮把结点的权值变成子树内权值的异或和,多次询问,求 \(m\) 轮后根节点的值。
由于多次询问,我们需要预处理。考虑深度为 \(d\) 的结点集合的贡献次数为 \(\dbinom{m-1+d}{d}\),即 \((m-1)\and d = 0\)。FWT 预处理子集内贡献和,每次查询一个集合的补集。
[「2022-03-24 省选模拟赛」树 (tree)]
\(子树内总方案数 - LCA 为子树内结点的方案数\)。
[「2022-03-24 省选模拟赛」黑白树 (astil)]
喵!
CF632E Thief in a Shop
算法 1
总大小不超过 \(10^6\),设出生成函数暴力多项式快速幂求出最后非 \(0\) 的位置即可。
算法 2
设 \(f_{i,j}\) 表示总价值为 \(i\) 时最少需要几个物品,直接用这个做问题很大。把所有数减去最小值,最后再加回来,再用这个 dp 就很对了。
03.25
[「2022-03-25 省选模拟赛」一之濑帆波 (honami)]
二分答案,求距离 \(\le mid\) 最少需要多少关键点。维护子树中离 \(u\) 最远的未被覆盖的结点,和离 \(u\) 最近的关键点到 \(u\) 的距离即可。
常数优化:dfs 时寻址不连续,改成返回 pair
会快很多。
[「2022-03-25 省选模拟赛」堀北铃音 (suzune)]
对于一种颜色 \(x\),考虑其能贡献多少区间,把序列中颜色为 \(x\) 的位置值设成 \(1\),其余设成 \(-1\),即求有多少区间和 \(\gt 0\)。我们可以把一整段 \(-1\) 缩成一个元素,相当于在这一段 \(-1\) 的最右的位置加入这一整段的贡献。用线段树维护,线段树下标为前缀和的值。设加入当前这段 \(-1\) 后前缀和区间为 \([l,r]\),则 \([-n,l-1]\) 的端点都能产生贡献,而 \([l,r]\) 中的贡献形如 \((r-l+1)a_l + (r-l)a_{l+1}\dots\),线段树维护 \(\sum a_i\) 和 \(\sum ia_i\) 即可。
[ 「2022-03-25 省选模拟赛」少项式 (minomial)]
这里只有一个能过题的 \(O(qk^2+k^22^k)\) 暴力做法。
首先可以建出一个网络流模型,\(i\in[0,k)\) 建点表示对应下标的系数和,每个前缀限制差分成区间,对每个区间建点。则存在合法方案等价于最小割恰好为 \(n\)。暴力模拟赛,枚举与 \(S\) 连通的集合 \(A\),则一种割集的权值为 \(\dfrac{n}k(k-|A|)\sum\limits_{j=1}^{q} \min(v_{i}, \sum\limits_{x\in A} w_{i,j})\)
第 \(i\) 个区间内每种余数的权值在区间 \([\lfloor \frac{len_i}k\rfloor,\lfloor \frac{len_i}k\rfloor+1]\),且取后者的形成模意义下的一段区间(记为新区间)。设 \(f_{l,r,i,j}\) 表示新区间为 \([l,r]\),\(|A|=i\),新区间与 \(A\) 的交集大小为 \(j\) 的贡献和,可以预处理出来。答案即为 \(\dfrac{n}k(k-|A|) + \sum\limits_{i,j} f_{i,j,|A|,|A\cap I_{i,j}|}\),其中 \(I_{i,j}\) 表示模意义下 \([i,j]\) 中元素的集合。
03.26
无事发生。
03.27
谢队模拟赛。过于 duliu。
03.28
[IOI2008] Pyramid Base
二合一。
\(B=0\)
等价于寻找最大空正方形。不同于最大矩形使用单调栈,在这里使用尺取法:枚举正方形左边界,指针右边界,则竖直方向上的最大距离即求 \(01\) 序列的最大子段和。调整使得竖直方向最大边长小于水平方向。
\(B\gt 0\)
二分答案 \(len\),每个矩形相当于向上向左拓展 \(len\) 格,线段树维护矩形覆盖即可求出此时最小花费。
[IOI2008] Linear Garden
对于字典序的题目,还是考虑枚举前 \(i-1\) 位相等,第 \(i\) 位小于,后面任意的方案数。对于这题,相当于每次走向前的一条折线,只能在 \(y=1\) 和 \(y=-1\) 之间走的方案数,分从中间开始和从两边开始,容易计算。如果此前没碰过壁,则两种情况都有可能,否则只有一种。稍微讨论一下就好。
[IOI2008] Teleporters
神仙题。把序列离散化下来之后,每个点向其到达点的后一个点连边,这样有两种情况:
- 从出发点开始,到最后一个点结束。这种情况形成一条链。
- 从其它未经过点开始,形成一个环。
新加入一个传送器时,我们也有两种决策:
- 把一个环连入链。
- 新增一个单独的环。
每次选取最大的环加入即可。
[TJOI2019]唱、跳、rap和篮球
枚举不合法位置数,方案数为 \(\dbinom{n-3i}{i}\) 与四个 EGF 的卷积的乘积。
03.29
「2020-10-04 联考」 奥法之劫 (offa)
每个位置能匹配 \(\{b\}\) 的哪个位置是固定的。设 \(f_{i}\) 表示考虑前 \(i\) 个位置的最小花费。转移:
树状数组与前缀和维护即可做到 \(O(n\log n)\)。
把和式拆成 \([a_{k}\gt a_{j} \land p_{k}\gt 0]\) 与 \([p_{k}\lt 0]\) 两部分。对于一个位置,其对应的 \(a_{j}\) 是确定且容易预处理的。维护 \(g_{b_{a_i}} = \min\{g_{b_{a_i-1}} + \sum\limits_{k}[a_{k}\gt a_{j} \land p_{k}\gt 0]p_k\}\),在维护求和部分的差分,每次加入权值时直接定位到对应的值上。
「2021-03-21 联考」伐木累 (famulei)
按照对角线 dp,分别设 \(f_{i,j,S},g_{i,j,S}\) 表示考虑到第 \(i\) 条对角线从右上到左下的第 \(j\) 个格子,对角线下一个的覆盖状态。转移时枚举这一个的方向,利用 \(S\) 中信息即可判断往右/下倒的方案数。
「2021 省队集训 day7」粒子物理 (particles)
记忆化并且每次询问做到 \(O(\min(k_x,k_y))\) 的复杂度,总复杂度即为 \(O(m\sqrt{m})\)。实现上,把询问离下来,挂到较小的粒子上,相同询问合并掉。把所有折返点按到达时间排序之后逐个枚举即可,维护每个粒子当前到哪个折返点。走到最后一个折返点的情况需要特判。
「微课 3.6.8&9 例 3」游戏
考虑每个 \(t(p)\) 对应多少种 \(p\)。筛出 \([l,r]\) 中无法被别的数干掉的,设有 \(k\) 个,枚举 \(t(p)=i\),则第 \(i\) 个位置上一定是筛出的数,容易用组合数写出答案。
「2020-3-29 联考」因数 (dzi)
即求 \(\sum\limits_{p\in \mathbb{P}} \sum\limits _{i\ge 1} \lfloor \dfrac{n}{p^i}\rfloor = \sum\limits_{p\le n} \lfloor \dfrac{n}{p}\rfloor + \sum\limits _{i\ge 2} \lfloor \dfrac{n}{p^i}\rfloor\),后面的部分只需枚举 \(p^2\le n\) 的质数,直接暴力做。
对于前面的部分,考虑求 \(g_i =\sum [\lfloor \dfrac{n}{p}\rfloor=i]\)。类似 min25 筛的思路,我们枚举最小质因子逐步筛去合数的贡献。设 \(f_{i,j}\) 表示考虑了前 \(i\) 个质数,\(1\sim j\) 的答案(即上式)。初值 \(f_{0,i} = i-1\),不难得到转移:
其中 \(p_i\) 表示第 \(i\) 个质数。第一维滚动数组。同样类似于 min25 筛,我们只会用到形如 \(\lfloor \dfrac{n}{i}\rfloor\) 的数,因此只需要 \(O(\sqrt n)\) 个位置,整除分块预处理出来即可。
好吧这就是 min25 筛的前半部分。
03.30
学习 min25 筛,见学习笔记。
「2021 省队集训 day5」背包 (pack)
对于这一类问题,我们有一般性的思路,即按照权值的大小关系考虑每一种可行的选取方案,同时构造一种后继状态的设计,满足:
- 每一种选取方案恰好被考虑一次;
- 转移形成的外向树满足祖先到儿子存在偏序关系。
只要解决了后继状态的设计问题,剩下的就是用堆或者其它数据结构来维护当前的极值即可。
对于这道题,由于模型比较复杂,我们可以先从比较简单的情况开始考虑。
- \(m=1,l=r\)
排序,最小的选法是选择前 \(l\) 个。对于后继状态,记三元组 \((p,c,lim)\),表示前缀 \([1,p]\) 还没被动过,当前考虑右移的位置为 \(c\),不能移动的前缀从 \(lim\) 开始。考虑这样一个策略:每次要么把当前位置右移,要么把当前位置更改为其前面最后一个可右移的位置。这样显然满足上面两个条件。
- \(m=1,l\lt r\)
把每一种长度的初始状态都加入堆中就转化为上面的情况。
- \(m\gt 1\)(即本题一般情况)
每一种类的权值取值是独立的,因此我们可以分开考虑。每一种物品内部可以看作 \(m=1\) 的黑箱,我们只需要支持查询其中第 \(k\) 大方案。而对于整体,我们也可以用类似的思路:把所有种类按对答案的最小增量排序,初始用处于最优状态表示其还未被考虑。记二元组 \((x,y)\) 表示当前在改前 \(x\) 种物品,当前物品 \(x\) 选到第 \(y\) 小方案,则我们的后继状态可以是:
- 当前物品选择下一个权值;
- 把当前物品变为下一种物品,相应地要给下一种物品选到次优状态;
- 把当前物品变为下一种物品,相应地要给下一种物品选到次优状态,同时把上一个当前物品退回到最优状态。为了保证每个状态只被考虑一次,这种转移必须只能在处于次优状态时进行。
每种物品内部用堆维护,整体再用堆维护即可。
03.31
「2022-03-31 省选模拟赛」BFS (bfs)
设 \(f_i\) 表示考虑 \([1,i]\) 的点的答案。有转移
其中 \(w_{j+1,i}\) 表示 \([1,j]\) 与 \([j+1,i]\) 之间多少结点有边。注意 \(j\) 能转移到 \(i\) 当且仅当 \([1,j]\) 与 \([i+1,n]\) 间没有连边(否则后面的点 bfs 序反而更前)。
算法 1
这是一个比较套路性的优化。\(w_{i,j}\) 可以使用主席树维护前缀信息求出,转移合法性的判断也可以用这个求。这个方程看着就很像决策单调性,随了几张图发现满足,所以二分栈决策单调性优化,时间复杂度 \(O(n\log n)\)。
算法 2
这是一个依赖特殊性质的优化。每个 \(i\) 能转移到一个后缀,且转移的权值不超过一个单调序列,即 \(f_{i+1}\le f_i+1\)。因此只需要对每一个 \(i\) 找到其能转移的第一个结点即可。
「2022-03-31 省选模拟赛」铁饭饭 (ironricerice)
\(K=1\) 和 \(K=N\) 的构造十分平凡,但这可以带来一些启发:把两者结合起来,就像两种暴力结合起来(经典的对询问分块)。好好利用队列长度的限制,我们把所有元素每 \(\dfrac{K}{2}\) 个分一块,每次查询两个块。这样刚好利用完了整个队列,问题在于第一次有很多浪费。因此我们考虑每次不止塞两块进队列,而是尽可能多塞,我们把这种塞队列称为一次行动。同时需要保证一次行动中不能把两个相同的块塞进队列。
把问题抽象一下,这相当于是一张完全图,每次走一条不经过重复结点的路径,求最少需要多少次能覆盖边集。题解给出了一个巧妙的构造:从每个点 \(u\le \dfrac{N}{2}\) 出发,依次遍历 \(u-1,u+1,u-2,u+2,u-3\cdots\),可以证明这是合法的。
「2022-03-31 省选模拟赛」境外势力 (covid)
设 \(f_{t,i}\) 表示第 \(i\) 个人在前 \(t\) 天被感染的概率,则答案为 \(\sum\limits f_{T+1,i}\)。如果此人的第 \(t\) 天被感染,则存在这天的一次行动使其被感染,补集转化,求每次行动都不被感染的概率。记 \(p_{i,j}\) 表示第 \(i\) 个人前往第 \(j\) 个地点的概率,\(q_{i,j} = (1-p_{i,j})^{b_i}\)。我们可以把地点和家庭分开考虑。以地点为例,家庭和其类似。则第 \(t\) 天 \(i\) 没被感染的概率为
维护连乘部分的总乘积,每次除一个逆元即可。