动态规划做题记录
CF2041J. Bottle Arrangement
因为 \(b\) 两两不同,因此不论是否 \(-1\),顺序都不会改变,结合单峰序列的要求,不难想到对 \(b\) 排序,则前 \(k\) 大的数在 \(a\) 中的位置一定连续,所以一个直接的想法是令 \(f_{i,l,r}\) 表示前 \(i\) 大的数放进区间 \([l,r]\) 内的最小花费,则答案即为 \(f_{n,1,n}\),然而复杂度为 \(O(n^2)\)。
换一种思路,考虑对于 \(f_{i,l,r}\) 来说,其有值当且仅当 \(\forall p\in[l,r],a_p\ge b_i\) 且只有 \(a_l,a_r\) 中的至多一个的值为 \(b_i\)。不妨令 \(g_{i,p}\) 表示是否存在一个区间 \([l,r]\supseteq p\) 使得 \(f_{i,l,r}\) 有值,则不难看出 \(\forall 1\le i\le n,g_{i,p}=1\) 的 \(p\) 可以作为一个 \(b_1\) 的合法起始位置。考虑如何判断这一点,不难发现我们只需要找到所有长度 \(\ge i\) 的极长的 \(>b_i\) 和 \(\ge b_i\) 的连通块即可,因为只有这些位置的 \(g\) 为 \(1\),之后简单差分维护即可。至于如何找到这些连通块,可以设立一些相隔为 \(i\) 的关键点,则每一个满足条件的连通块定然经过至少一个关键点。连通块的维护利用并查集即可。复杂度是 \(O(n\ln n)\) 的。
CF2040F. Number of Cubes
观看题面很难不想到 Burnside
引理,考虑公式
则只需要求出在所有置换下的不动点数量即可。考虑对于一维来讲,若长度为 \(n\) ,移动 \(x\) 次,则会划分出长为 \(\gcd(x,n)\) 的循环,共 \(T=\dfrac{n}{\gcd(x,n)}\) 个循环,则每个颜色在一个循环中应当出现 \(\dfrac{d_i}{T}\) 次,则总方案数为 \(\left (\begin{matrix}\frac{n}{T}\\\frac{d_1}{T},\frac{d_2}{T},\cdots,\frac{d_k}{T}\end{matrix}\right)\)。拓展到三维的情况,若三维分别移动 \(p,q,r\) 次,则会产生 \(T=\text{lcm}(\dfrac{a}{p},\dfrac{b}{q},\dfrac{c}{r})\) 个循环,计算不动点的方案是不变的。然而注意到每一个颜色的次数都应当为整数,因此有 \(T\mid \gcd(d_1,d_2,\cdots,d_k)\)。考虑对于所有 \(\gcd(d_1,d_2,\cdots,d_k)\) 的因数 \(T\) 预处理出 \(\left (\begin{matrix}\frac{n}{T}\\\frac{d_1}{T},\frac{d_2}{T},\cdots,\frac{d_k}{T}\end{matrix}\right)\),则可以枚举 \(a,b,c\) 的因子后 \(O(1)\) 求解,不难看出复杂度是 \(O(T(\sigma(\gcd)k+\sigma(a)\sigma(b)\sigma(c)))\),其中 \(\sigma(d)\) 是 \(d\) 的因子个数。
CF2029G. Balanced Problem
首先不难考虑到可以将最终序列 \(a\) 中 \(>V\) 的数删去,并且将相邻相同的数合并(\(a\) 不变,\(c\) 相加),这样只会剩余 \(O(V)\) 个数,接着可以考虑 dp
。
考虑对于一个单独的 \(v\),令 \(f_{i,j,k}\) 表示有 \(j\) 个后缀操作和 \(k\) 个前缀操作覆盖了 \(i\),则不难看出,如果 \(a_i+j+k\ne v\),则这一位没有意义,应当直接继承上一次的信息,这样可以留给后面最大的操作空间。不然我们可以选择结束一些前缀操作,或者开始一些后缀操作。因此我们有转移方程
显然可以利用树状数组做到 \(O(V^2\log^2V)\)。考虑到 \(j+k=v-a_i\),因此在二维矩阵中我们更新了一条斜线,每一次我们都在该点的右上角部分找一个最大值更新。不难看出每一次的点的可行转移只比上一次的转移多一行和一列,因此可以通过维护行和列的树状数组做到 \(O(V^2\log V)\)。
考虑如何对于全局的询问求解,考虑改动 dp
状态,令 \(f_{i,j,k}\) 表示有 \(j\) 个后缀操作和 \(v-k\) 个前缀操作覆盖了 \(i\),注意这里的 \(v\) 是变量,那么我们的转移方程应当改为
这一次我们发现更新的斜线与 \(v\) 无关,于是正常 dp
得到的 \(f\) 可以应对所有询问,询问 \(i\) 的答案在 \((0,0),(i,i)\) 的矩形中取最大值。
CF2020F. Count Leaves
打表后我们注意到对于一个固定 \(d\),如果 \((a,b)=1\),则 \(f(ab)=f(a)f(b)\)。于是我们只需要了解 \(f(p^k)\) 的值即可,不难猜出 \(f_d(p^k)=\binom{k+d}{d}\)。则对于 \(i=\prod p_i^{\alpha_i},f_d(i^k)=\prod\binom{\alpha_ik+d}{d}\)。
考虑使用 min_25
筛解决这个问题,复杂度是 \(O(\frac{n^{\frac{3}{4}}}{\log n})\) 的。
CF1954F. Unique Strings
首先考虑 Burnside
引理,然而题目中给出的字符串关于置换不封闭,因此我们需要考虑转化。不妨考虑求解 \(1\) 的个数不超过 \(k+c\) 个且至少有一个长度为 \(c\) 的 \(1\) 连续段的本质不同字符串数(循环同构)。
先特判 \(k+c=n\) 的情况,然后考虑对于一个长度为 \(d\) 的循环,我们有多少种填写的方案数,令 \(f_d\) 表示这个数。对于 \(d\le c\),如果存在长度为 \(c\) 的连续段,则一定全部为 \(1\),而我们已经特判过。对于 \(d>c\),考虑正难则反,我们尝试求解 \(1\) 的个数不超过 \(k+c\) 个且循环下没有长度为 \(c\) 的连续段的方案数。我们可以先枚举两端的 \(1\) 的个数,然后考虑中间怎么填。令 \(g_{i,j}\) 表示长度为 \(i\),恰好有 \(j\) 个 \(1\) 且没有长度为 \(c\) 的连续段的方案数。有转移方程
前缀和优化即可。对于 \(g\to f\) 的过程,枚举每一个循环有多少个 \(1\) 后容斥即可。最后答案即为 \(\sum\limits_{i=1}^{n}f_{\gcd(n,i)}\),除以总置换数 \(n\) 即可。
CF1864H. Asterism Stream
首先我们进行一些宏定义:令 \(k=\dfrac{1}{2},\{a,b\}=ak^{bx}\)。
考虑一个朴素的 \(O(n)\) dp
:
假设现在对于区间 \([2l,2r]\) 我们可以将 \(\forall x\in[2l,2r]\) 的 \(f_x\) 写成同样的若干个 \(\{a,b\}\) 的和,则我们一定可以用一些 \(\{a,b\}\) 表示 \(x\in[l,r]\) 的所有 \(f_x\)。
考虑 \(f_r=kf_{r+1}+kf_{2r}+1\),于是我们有 \(f_{r-1}=k^2f_{r+1}+kf_{2r-2}+k^2f_{2r}+k+1\),继续推下去,我们有
换元后得到
对于第一个部分,我们可以直接利用已知的 \(f_{r+1}\),不难看出其等于 \(k^{r+1}f_{r+1}·k^{-x}=\{k^{r+1}f_{r+1},-1\}\)。对于最后面的求和,是一个平凡的几何级数,不难看出其值为 \(2-k^{r-x}=\{2,0\}+\{-k^r,-1\}\)。对于中间的部分,利用已知的 \([2l,2r]\) 内的 \(\{a,b\}\) 和,我们有
利用 \(\{a,c\}+\{b,c\}=\{a+b,c\}\) 化简后单次最多有 \(\log\) 个 \(\{a,b\}\),复杂度可以简单做到 \(O(T\log^3n)\)。
CF1810G. The Maximum Prefix
对于前缀和最大值有两种典型的方法:
- 从前往后算,需要维护当前前缀和 \(\text{sum}\) 和当前最大值 \(\text{mx}\),填入 \(a\) 时 \(\text{sum}\xleftarrow{+} a,\text{mx}\xleftarrow{\max}\text{sum}+a\),然而需要维护两个值对本题来说无法接受。
- 从后往前算,需要维护当前前缀最大值 \(\text{mx}\),填入 \(a\) 时 \(\text{mx}\gets\max(\text{mx}+a,0)\)。
根据方法 \(2\) 我们可以简单给出状态设计:\(f_{i,j}\) 表示 \([i,l]\) 的最大前缀和为 \(j\) 的概率,则可以简单列出转移方程:
那么答案即为 \(\sum\limits_{i=0}^{l}f_{1,i}h_{i}\),这样对于一个 \(l\) 的复杂度是 \(O(l^2)\) 的,然而对于所有 \(l\) 的求解复杂度是 \(O(n^3)\) 的。考虑到每一次的转移本质上只有初值不同,其余的转移方程是相同的,于是我们可以利用一个经典的 trick:反推贡献系数。我们考虑 \(f_{i,j}\) 对答案的贡献系数 \(g_{i,j}\),那么我们有转移方程:
这样对所有的 \(l\) 都成立,答案即为 \(g_{l+1,0}\),复杂度为 \(O(n^2)\)。
CF1770F. Koxia and Sequence
注意到整个序列具有对称性,如果设 \(f(i,t)\) 表示 \(a_i=t\) 的合法序列个数,那么应该有 \(f(1,t)=f(2,t)=\cdots=f(n,t)\),因此如果 \(n\) 为偶数则答案一定为 \(0\),如果 \(n\) 为奇数,则我们只需要考虑在所有合法序列中 \(a_1\) 的异或和。接着考虑拆位,即对于第 \(i\) 位考虑 \(a_1\) 的第 \(i\) 位为 \(1\) 的合法序列数量。
然而按位或的条件很难限制,考虑到如果 \(g(y)\) 表示 \(y\) 的所有子集作为按位或的答案异或和,那么 \(y\) 的所有子集的 \(g\) 的异或和应当和真实答案相等。考虑枚举所有的子集对其求值。
通过 Lucas 定理的推论和 Kummer 定理我们得知:\(\begin{aligned}{n\choose m}\end{aligned}\bmod2=[m\subseteq n]\)。我们可以双向利用这一点,则 \(\sum_{\substack{t_1+t_2+\cdots+t_n=x\\t_1\cup t_2\cup\cdots\cup t_n\subseteq y}}\equiv\sum_{\substack{t1+t2+\cdots+t_n=x}}\prod {y\choose t_i}\pmod 2\),继续考虑 Vandermonde 恒等式,我们有 \(\sum\limits_{\substack{t1+t2+\cdots+t_n=x\\}}\prod {y\choose t_i}={ny\choose \sum t_i}={ny\choose x}\),考虑到因为 \(a_1\) 需要记入贡献,所以其肯定需要有 \(2^i\),因此 \(f(y)\) 的答案的第 \(i\) 位即为 \(\begin{aligned}{ny-2^i\choose x-2^i}\end{aligned}\bmod 2=[x-2^i\subseteq ny-2^i]\),枚举 \(y\) 的子集和 \(i\) 求解即可。
CF1761F1. Anti-median (Easy Version)
考察任意三个连续的位置 \(p_1,p_2,p_3\),有 \(p_2>p_1,p_2>p_3\) 或 \(p_2<p_1,p_2<p_3\),对于所有连续的位置联立,我们得出这个序列应该呈波浪状排布,即所有偶数位置为局部最大值,奇数位置为局部最小值(或恰好相反)。不难发现两者没有本质区别,下文只讨论第一种,另一种同理可得。
接着考察任意五个连续的位置 \(p_1,p_2,p_3,p_4,p_5\),假设 \(p_3\) 的位置为偶数,有 \(p_3>p_2,p_3>p_4\),则 \(p_3>p_1\) 或 \(p_3>p_5\),对于所有偶数位置联立,我们得出偶数位置的数应当先增后减,同理可得奇数位置的数应当先减后增。
接着考虑任意 \(2m+1(m>2)\) 个连续的位置 \(p_{i+j}(0\le j\le 2m)\),假设 \(p_{i+m}\) 的位置为偶数,有 \(p_{i+m}>p_{i+m-1},p_{i+m}>p_{i+m+1}\),并且由于偶数的性质,我们得出其一定大于一边的所有偶数,进而大于该边的所有数,加上另一边的相邻的数,\(p_{i+m}\) 至少大于 \(m+1\) 个数,则 \(p_{i+m}\) 必然不为中位数,对于奇数同理(相反也同理可得)。
根据上面,我们可以得出这个序列呈波浪状排布,即所有偶数位置为局部最大值,奇数位置为局部最小值(或恰好相反),且偶数位置的数先增后减,同理可得奇数位置的数先减后增(或恰好相反)是这个序列合法的充要条件。考虑从偶数的最大点走到 \(2\),此时有 \(p_2>p_1\),接着可以从 \(1\) 走到奇数的最小点,不难看出整个过程的 \(p\) 单调递减。相反,可以从偶数的最大点走到 \(n-[2\nmid n]\),此时有 \(p_{n-[2\nmid n]}>p_{n-[2\mid n]}\),接着可以从 \(n-[2\mid n]\) 走到奇数的最小点,不难看出整个过程的 \(p\) 单调递减。这启发我们按照 \(n-[2\nmid n],\cdots,4,2,1,3,\cdots.n-[2\mid n]\) 的顺序对序列重排,则对于任意 \(k\),应当有 \([1,k]\) 在序列中对应的位置连续,由此考虑区间 dp。
令 \(f_{l,r}\) 表示区间 \([l,r]\) 对应 \(\left\{\begin{aligned}&r-l+1,&&l\le r;\\&r+(n-l+1),&&r<l.\end{aligned}\right.\) 的方案数,则根据上面的性质,最后一个数只可能位于 \(l\) 或 \(r\)。这样的 dp 保证了偶数位置和奇数位置的单调性正确,因此只需要保证序列的形状正确即可,只需要 \(O(1)\) 判断是否可行。复杂度为 \(O(n^2)\)。
LG3642. [APIO2016] 烟火表演
不难想到一个将简单的转移方程:令 \(f_{u,x}\) 表示 \(u\) 的子树内所有烟花到 \(u\) 的距离为 \(x\) 的方案数,则有转移方程
于是我们有一个 \(O(n(\sum w)^2)\) 的做法,考虑将这个方程看作关于 \(x\) 的函数 \(f_{u}(x)\),我们去考虑转移过程中函数图像的变化。先手玩,发现这个函数是一个分段函数,并且每一段的斜率单调递增,且差值为 \(1\),那么最优取值是斜率为 \(0\) 的段,记为 \([L,R]\)。令 \(F_{v}(x)\) 表示 \(v\) 对 \(u\) 的贡献,则 \(F_v(x)=\min\limits_{y\le x}f_{v}(y)+|w-(x-y)|\)。
对于这个函数进行分类讨论:
- \(x< L\),此时 \(y=x\) 一定最优,此时 \(F_v(x)=f_v(x)+w\)。否则后半部分的代价最多减少 \(1\),因为观察出的函数的性质,前半部分增加的的代价一定比 \(1\) 大,则总代价不减少。
- \(L\le x<L+w\),此时 \(y=L\) 一定最优,此时 \(F_v(x)=f_v(L)+w-(x-L)\)。因为直到 \(L\) 前,前半部分的代价是不变的,而后半部分代价一直减少,之后同理总代价不减少。
- \(L+w\le x<R+w\),此时 \(y=x-w\) 一定最优,此时 \(F_v(x)=f_v(x-w)=f_v(L)\)。因为此时不管是前半部分还是后半部分,代价都是最小的。
- \(x\ge R+w\),此时 \(y=R\) 一定最优,此时 \(F_v(x)=f_v(R)+(x-R)-w\)。同理可以证明不管怎样调整总代价均不减少。
汇总一下就是
考虑 \(f_v\to F_v\) 的过程是怎样的:将 \(<L\) 的部分向上平移 \(w\) 格,将 \([L,R]\) 的部分向右平移 \(w\) 格,并在这部分两边分别加入斜率为 \(-1,1\) 的线。我们发现这个函数依旧具有原来的性质,我们可以考虑利用 slope trick,维护这个函数图像的拐点,则两个图像相加相当于拐点的合并,利用可并堆可以简单维护这个事情。对于 \(f_v\to F_v\) 的变化,相当于删除 \(L\) 后的所有拐点,接着加入 \(L+w,R+w\) 两个位置的拐点。对于答案的求解,不难考虑到我们已知 \(f_1(0)=\sum w\),利用函数的性质,可以简单算出答案。
LG4383. [八省联考 2018] 林克卡特树
首先不难将题目转成选取不相交的 \(k+1\) 条链使得这些链的边权和最大。那么有一个简单的 dp 设计:令 \(f_{u,k,0/1/2}\) 表示点 \(u\) 的子树内有 \(k\) 条链并且 \(u\) 单独在链上/ \(u\) 和一个儿子在链上/ \(u\) 不在链上或 \(u\) 和两个儿子在链上的最大边权和。那么 dp 转移是显然的:
这样复杂度是 \(O(nk)\) 的。不难考虑到答案对于 \(k\) 形成的图像应当是一个上凸包,因此考虑 wqs 二分。对于一个斜率,随着其增大,在凸包上的切点坐标将会减小,因此可以通过二分斜率找到 \(k+1\) 为切点的斜率,然后可以求解。考虑如何找到一个斜率下的切点坐标,根据定义,直线在切点处的截距最到,即 \(b=h(x)-kx\) 最大,因此我们只需要找到使 \(h(x)-kx\) 最大的位置即可。考虑到 \(x\) 为选取的链的个数,不妨看作每一条链均有 \(k\) 的代价后跑 dp 即可。
注意到此时我们的 dp 没有选取个数的限制,直接跑即可。然而求解的需要,因此我们维护一个二元组,同时维护当前最优解的选取链的个数即可。
需要注意的是因为凸包是离散的,因此可能找不到一个斜率使得 \(k+1\) 处为切点,这个时候我们可以让 dp 总是取选链个数最大(或最小)的方案,对于最后一个坐标大于等于(或小于等于)的切点统计答案即可。
CF1342F. Make It Ascending
考虑到直接找到一个序列变成单调序列是困难的,但我们不难发现我们总是可以将最终的序列看作将原序列分成一些集合,将每个集合中的数全部加到一个位置上的结果,因此我们不妨直接 dp 找出最优的最终序列的集合和位置,因此设 \(f_{i,S,p}\) 表示选择了 \(i\) 个集合,选择的点集为 \(S\),第 \(i\) 个集合归并到的点为 \(p\) 时第 \(i\) 个集合的和的最小值(因为最小值肯定有利于我们后面的选择)。令 \(p\in S\) 表示 \(S\) 对应的 \(p\) 为 \(1\),那么可以轻松得出转移方程:
于是我们愉快的得到了一个 \(O(n^33^n)\) 的做法,这个做法不是很优,但可以通过。考虑一个优化:当选择点集时,我们肯定期待选择一个较小的 \(p\),因为这样后面选择的范围会更广。所以我们转而选择刷表,这样对于一个确定的 \(T,q\) 来说,我们只需要找到可行的 \(S\setminus T\) 中最小 \(>q\) 的 \(p\) 即可,这个可以用 __builtin_ctz
实现,那么复杂度会降为 \(O(n^23^n)\)。记录下最优转移点即可输出方案。
CF1239E. Turtle
不难考虑到如果我们已经确定上面的数集,那么最优方案的已知的:上方单调递增,下方单调递减,利用调整法可以简单证明。现在考虑最大路径,假设从第 \(i\) 位开始拐弯的路径和为 \(S_i\),则 \(S_{i+1}=S_i+a_{i+1}-b_i\),因为 \(a_{i+1}\) 单增,\(b_i\) 单减,所以看出 \(S_{i+1}-S_{i}\) 单调递增,于是 \(S\) 的最大取值一定出现在 \(1\) 或 \(n\)。所以我们的最大路径和为 \(\max(\sum a+b_n,\sum b+a_1)\)。
与此同时我们应该可以简单看出 \(a_1,b_n\) 的值应当为最小的两个数,利用调整法证明即可,那么我们只需要让剩下的 \(2n-2\) 个数分成两个长为 \(n-1\) 的序列,并且 \(\max(\sum a,\sum b)\) 最小即可。考虑到 \(\sum a+\sum b\) 是一定的,假设为 \(s\),只需要让一边在 \(\ge \lfloor\frac{s+1}{2}\rfloor\) 前提下最小即可,不难看出可以利用背包 dp 简单实现,并且印因为我们只考虑可行性,可以用 bitset
优化,但需要注意此时不能滚动数组,否则难以进行构造。复杂度是 \(O(\frac{n^2\sum a}{w})\) 的。
CF1403C. Chess Rush/LG6806. [CEOI 2020] 象棋世界
考虑有 \(5\) 种不同的棋子我们分类讨论。
-
对于兵来说,如果 \(C_1=C_R\),那么可以走到且步数为 \(R-1\),而且只有 \(1\) 种走法;否则不可能走到对应位置。
-
对于车来说,如果 \(C_1=C_R\),那么可以一步走到,且只有一种走法;否则可以两步走到且有两种走法。
-
对于后来说,我们先默认 \(C_1\le C_R\),因为交换两者的答案是不变的,如果 \(C_1=C_R\lor(C_1=1\land C_R=C)\),那么可以一步走到且只有一种走法;否则一定可以在两步之内走到,可以在两步之内走到目标点的路径可以简单讨论,有以下几种:
- 像车一样走两次直线。这种情况一定存在且贡献为 \(2\)。
- 像象一样走两次斜线。这种情况不一定存在,因为合理的路径可能超出棋盘或通过这种方式根本无法到达目标点,因此需要对两种路径均进行判断。
- 先竖向走一条直线,然后直接走斜线到目标点。这种情况一定存在且贡献为 \(2\)。
- 先横向走一条直线,然后直接走斜线到目标点。这种情况不一定存在,因为合理的路径可能超出棋盘,注意到 \(C\le R\),因此我们可以直接判断 \(C_R\) 是否为 \(C\),当且仅当命题成立对答案有 \(1\) 的贡献。
-
对于象来说,我们先判断是否可达,判断 \(C_1+C_R+R+1\) 的奇偶性即可。接着考虑怎么样才能求出最小步数,一个简单的想法是每一次斜向移动都移动到不能再移动,这样子一定步数最少,但单纯的路径可能无法到达目标点,而是会在其上方相差 \(\Delta\) 的距离。我们考虑对路径进行微调:将一个拐点向下移动一格,我们发现,此时的 \(\Delta\) 会减少 \(2\),也就是说我们需要微调 \(\frac{\Delta}{2}\) 次,那么就是一个简单的组合数,假设有 \(k\) 个拐点,那么最小步数为 \(k+1\),总方案数为 \({k+\frac{\Delta}{2}-1\choose\frac{\Delta}{2}}\)。考虑到两侧的走法不一定都能达到最优解,因此对两侧单独跑一遍后取更优即可。
还有一个问题是我们的组合数 \(k+\frac{\Delta}{2}-1\) 的范围是 \(O(\frac{R}{C})\) 的,从而我们难以进行预处理。但考虑到 \(\frac{\Delta}{2}\) 的范围是 \(O(C)\) 的,因此采取 \(O(C)\) 求组合数的方法即可。
-
对于王来说,最少步数容易发现一定是 \(R-1\),而且只会朝上走。而对于方案数,我们设 \(f_{i,j}\) 表示从起点走到 \((i,j)\) 的方案数,可以简单列出 dp 转移:
\[f_{i,j}=\left\{\begin{aligned}&[j=C_1],&&i=1;\\&f_{i-1,j}+f_{i-1,j+1},&&j=1;\\&f_{i-1,j-1}+f_{i-1,j}+f_{i-1,j+1},&& 1<j<m;\\&f_{i-1,j-1}+f_{i-1,j},&&j=m. \end{aligned}\right. \]而不难看出这个内容可以简单用矩阵表示,也就是
\[\begin{bmatrix}f_{1,1}&f_{1,2}&\cdots&f_{1,C}\end{bmatrix}\times\begin{bmatrix}1&1&0&\cdots&0&0&0\\1&1&1&\cdots&0&0&0\\0&1&1&\cdots&0&0&0\\\vdots&\vdots&\vdots&\ddots&\vdots&\vdots&\vdots\\0&0&0&\cdots&1&1&0\\0&0&0&\cdots&1&1&1\\0&0&0&\cdots&0&1&1\end{bmatrix}^{R-1}=\begin{bmatrix}f_{R,1}&f_{R,2}&\cdots&f_{R,C}\end{bmatrix} \]然而普通的方法是 \(O(C^3\log R)\) 的,难以通过本题,我们需要找一种高效的乘法转移。通过观察我们发现这个矩阵的任意次幂均关于主对角线和副对角线对称,这启发我们快速求出其中的一部分,然后推出其余部分的值。通过大胆观察,小心求证,我们发现这个矩阵还满足,有
\[\forall i+j-1\le C,A_{i,j}^n=A_{i-1,j-1}^n+A_{1,i+j-1}^n \]这个性质可以通过数学归纳法简单证明,例如当 \(i=2\) 时:
\[A_{1,i}^{n+1}=A_{i,1}^{n+1}\Rightarrow A_{1,i-1}^n+A_{1,i}^n+A_{1,i+1}^n=A_{i,1}^n+A_{i,2}^n\Rightarrow A_{2,i}^n=A_{1,i-1}^n+A_{1,i+1}^n \]对于得到的式子,因为对称性,所以我们应当认为 \(2\le i\le C-1\),归纳证明是容易的。于是我们只需要求出第一行就可以递推出所有内容,于是复杂度降至了 \(O(C^2\log R)\) 可以通过。
CF613E. Puzzle Lover
先特判 \(|w|\in\{1,2\}\) 的情况,这两种情况是容易的。
考虑所有可能的路径形态,不难看出一定是前后有一段折返,而中间是单向路径。利用哈希可以简单求出以某一列为起终点的两个方向的可以匹配的折返的信息,这个过程是 \(O(n^2)\)。对于中间路径端的信息,我们可以写一个简单的 dp 去处理中间的路径段的信息,初始化可以用左侧折返的信息,最后根据已知信息匹配右侧折返即可,总复杂度是 \(O(n^2)\)。
但是这个样子我们只得到了形如从左到右的路径的信息,我们可以将 \(w\) 翻转后再跑一次。然而这样子会有重复,考虑到重复的内容一定只有单独存在的折返(没有路径部分),那么我们只在一次统计是将折返加入答案即可。
CF1466H. Finding satisfactory solutions
考虑对题面进行神秘转换:对于一个排列 \(s_i\),对于 \(i\),用白边连接 \(p_i\) 以前的所有点,用黑边连接 \(p_i\),那么不存在更优解当且仅当不存在有白边的环。按照新增的环去分配,所有黑边的点不变劣,而白边的点变优,而这种方式更优。
对于原图来讲,黑边一定形成一些环,不妨在最后的图中对这些环缩点,那么会得到一个 DAG,而且 DAG 中全是白边,于是问题转化成对一些点连接 DAG 相关的问题。考虑如果一个点存在 \(d_i\) 条白边的出边,说明这些出点都在 \(p_i\) 前,并且可以随意排,剩下的 \(n-d_i-1\) 个都在 \(p_i\) 后,并且可以随意排,于是答案即为
考虑用 dp 去求解这个内容,更具体的,我们设 \(f_S\) 表示选择环的情况为 \(S\) 时的方案数,我们可以得到转移方程
\(k(A,B)\) 表示 \(B\) 中的点向 \(A\) 中的点连边的贡献,\(|S|\) 表示 \(S\) 中环的数量。前面的 \(-1\) 是因为枚举集合会重复连边,所以进行了容斥。考虑到 \(B\) 中的点不会相互影响贡献,因此计算一个点的贡献后 \(|B|\) 次方即可,\(|B|\) 表示 \(B\) 中点的数量,而我们也不关心 \(A\) 中具体有哪些点,只关心对应的数量,设为 \(s\)。于是对于一个点贡献应为
从而可以做到 \(O(3^n)\) 的复杂度,然而不够,我们考虑优化状态数。注意到对于转移,我们并不关心选择的环是哪些,而是关心选择的每种环的数量,于是我们可以对于这个内容进行状态压缩。我们发现这个东西的上限非常小,只有 \(1440\),则枚举子集可以在 \(O(1440^2)\) 的复杂度内实现。因为环是不同的,所以选择的环的方案还要乘上一些组合数,于是可以做到 \(O(1440^2 n)\)。
CF582D. Number of Binominal Coefficients
看到题面,考虑 Kummer 定理,我们有 \({a+b\choose a}\) 中质因子 \(p\) 的个数为 \(a,b\) 在 \(p\) 进制下加法的进位个数,这启发我们进行数位 dp。
考虑设 \(f_{i,0/1,0/1,c}\) 表示从高到低的前 \(i\) 为,\(a+b<A\)(或 \(a+b=A\)),钦定第 \(i-1\) 位不进位(或进位)且总共进了 \(c\) 位的方案数。于是我们只需要求出 \(A\) 的 \(p\) 进制表示后考虑 \(4\times4=16\) 种的转移即可,贡献系数是容易推出的。考虑到 \(\log 10^{1000}\approx 3321\),因此求解 \(A\) 的 \(p\) 进制表示的 \(O(\log A\log_p A)\) 和 dp 的 \(O(\log_p^2 A)\) 都是可以接受的。
AGC034E. Complete Compress
考虑 \(n\) 的数据范围肯定让我们想到暴力枚举每一个点作为最后的汇总点,可以以这个点为根,那么我们肯定要求选择的两个点不是祖先关系,否则肯定对于答案是无用的,于是最终的步数已经确定,我们将问题转化为是否可行。
因为两个点不为祖先关系,所以我们可以姑且认为两个点不在同一个子树中。于是我们考虑每一个子树需要被选择的次数是其中所有棋子的深度和,那么我们期望一个存在匹配方案使得两个匹配的点不在同一个子树内。一个经典的结论是,当所有子树的次数和不超过总次数的 \(\frac{1}{2}\) 时,定然有解。否则我们考虑最大的也是唯一一个 \(>\frac{1}{2}\) 的子树,显然我们被迫需要让它自己和自己匹配,也就是我们想要找出在这个子树内最大的匹配数,递归求解即可。我们综合所有匹配得出根节点的最大匹配数,并判断是否可行即可,复杂度是 \(O(n^2)\) 的。
AGC020E. Encoding Subsets
考虑求所有子集的合法压缩较为困难,我们不如考虑那些压缩的展开是原串的子集,设 \(f(S)\) 表示这个答案,那么我们分类讨论压缩字符串的第一位:
- 第一位是数字,这意味着我们将第一位和后面的分开考虑,也就是说后面的贡献应当为 \(f(S_{2\to |S|})\),而对于第一位的选择,不难看出如果原串为 \(1\),那么贡献要翻倍。
- 第一位是括号,这意味着我们将一些相同的位置压缩到了一起,不妨枚举每一段的长度和段的个数,假设为 \(|A|\) 和 \(k\),那么不难看出 \(A\) 应该为 \(S_{1\to |A|},S_{|A|+1\to 2|A|},\cdots,S_{(k-1)|A|+1\to k|A|}\) 的按位与的子集,只有这样才可以让每一个位置都合法,假设按位与为 \(w(|A|,k)\),那个这一段的方案数是 \(f(w(|A|,k))\),而后面的方案也不难看出为 \(f(S_{k|A|+1\to|S|})\)。
则不难看出 \(f(S)\) 可以表示为
我们考虑直接使用记忆化完成这个过程,虽然看上去总得状态数是 \(O(2^{|S|})\),但不难证明,这个状态数不会超过 \(5\times10^4\),于是可以通过本题。
AGC036D. Negative Cycle
考虑将原图转换成差分约束模型,那么图中不存在负环当且仅当保留的限制存在一组合法解。那么因为自带的 \(0\) 边不能删去,所以有 \(x_i\ge x_{i+1}\),因此我们考虑进行差分,得到 \(q_i=x_i-x_{i+1}\),那么我们有 \(q_{i}\ge 0\)。考虑保留其他边的限制:
- 如果保留边权为 \(-1\) 的边,即一条 \(i<j\) 的边,那么这说明 \(x_j\le x_i-1\),也就是 \(x_i-x_j\ge 1\),则 \(\sum_{k=i}^{j-1}q_k\ge 1\)。
- 如果保留边权为 \(1\) 的边,即一条 \(i>j\) 的边,说明 \(x_j\le x_i+1\),也就是 \(x_j-x_i\le 1\),则 \(\sum_{k=j}^{i-1}q_k\le 1\)。
概括上面的内容就是,如果我们钦定 \(q\) 的内容,那么如果区间 \([l,r-1]\) 的和 \(<1\),必须删去 \(l\to r\);如果和 \(>1\),必须删去 \(r\to l\)。
考虑 \(q_i\) 的取值内容,不难看出如果 \(q_i>1\),那么我们不如取 \(q_i=1\),因为这样一定可以省下 \(i+1\to i\) 的这条边。于是 \(q_i\) 的取值只有 \(0,1\)。不妨设 \(f_{i,j}\) 表示 \(i\) 为最后一个取 \(1\) 的位置,\(j\) 为倒数第二个取 \(1\) 的位置,那么是可以从 \(f_{j,k}\) 转移过来的。不难通过前缀和处理出转移系数,那么总复杂度为 \(O(n^3)\)。