省选数学专题 1 做题记录
省选数学专题 1 做题记录
A P7481 梦现时刻
由于有 \(\oplus\) 操作,所以我们只能快速求出 \(F(a,b)\) 然后 \(O(m^2)\) 求答案。考虑如何快速求出 \(F(a,b)\),有两条路可以选:\(O(1)\) 直接求出它的值,或者求出递推式 \(O(m^2)\) 求解。显然后者更靠谱。
那么现在直接推出递推式就行了,其实不是非常困难,需要用到的性质只有 \(\binom{n}{m}=\binom{n-1}{m}+\binom{n-1}{m-1}\) 一条:
然后我们就可以 \(O(m^2)\) 递推求出答案了。
B CF1863G Swaps
首先题目中给出了交换 \(i\) 和 \(a_i\) 位置上数字的这个条件,一个经典的套路是连边 \(i\to a_i\) 构建基环内向树,然后发现性质。接下来会发现,如果执行了一次交换操作后,两个位置上的数会变为 \(a_{a_i}\) 和 \(a_i\),那么此时 \(a_i\) 位置上的值就是 \(a_i\),也就是说此时我们不能再对 \(a_i\) 进行任何操作了。
那么这就说明对于一个点,我们只有一个点可以跟它换,也就是说每个点我们最多选出一个入度,总方案数就是 \(\prod(d_i+1)\)。此时会发现算出来答案不对,原因在于环上的贡献统计的不对。手玩一下会发现,如果环上的边选出了 \(k-1\) 条,此时环上的 \(k\) 个点也已经全部归位,而此时我们依然在统计这条链的链头处的入度的贡献,这就是不合法的情况。处理也是简单的,枚举一下链头,减去链头处入度的贡献即可。简单写一个判环即可,复杂度 \(O(n)\)。
C CF1707D Partial Virtual Trees
首先考虑虚树的要求:如果一个点不在虚树上,那么它最多只有一个子树内有点在虚树上。考虑树形 dp,设 \(f(i,j)\) 表示 \(i\) 子树内所有点在 \(S_j\) 仍有点在虚树中,到 \(S_{j+1}\) 所有点都不在虚树上的方案数。转移有两种:
-
\(i\) 在 \(S_j\) 中出现:
此时子树只需要在 \(S_j\) 之前被删除即可,转移方程为:
\[f(i,j)\gets \prod_{v\in son(i)} \sum_{k=0}^j f(v,k) \]令 \(g(i,j)=\sum\limits_{k=0}^j f(i,k)\),上式可以直接转移。
-
\(i\) 不在 \(S_j\) 中出现:
这表明 \(i\) 在 \(S_j\) 之前就被删除,根据上面的结论,留到 \(S_j\) 的只可能是 \(i\) 的某一个子树的点,而其他子树则同样要在 \(i\) 删除前被删除。转移为:
\[f(i,j)\gets \sum_{k=0}^{j-1} \sum_{v\in son(i)} f(v,j)\times \prod_{v'\in son(i)\land v'\ne v} g(v',k) \]利用前后缀积求出 \(\prod g(v',k)\) 之后求一遍前缀和,则上式也可以直接转移。
最后我们要求答案,先求出 \(G(i)=\prod\limits_{v\in son(1)} g(v,i-1)\),表示 \(k=i\) 时的答案。不过此时会发现一个严重的问题,我们在转移的时候实际上没有保证 \(S_i\ne S_{i-1}\),但是题目里保证了是真子集。设 \(F(i)\) 表示真正的答案,根据插板法经典结论,可以得到:
然后直接二项式反演就可以得到真正的 \(F(i)\),直接输出即可。复杂度是 \(O(n^2)\) 的,可以通过。
D P8859 冒泡排序
哥们又来做拼好题了。
-
\(type=1\):
考虑从大到小往序列里插数,一个数需要进行冒泡操作当且仅当它前面有比它大的数,那么设 \(dp(i,j)\) 表示当前插到第 \(i\) 大的数,需要的操作数为 \(j\) 的序列数,转移为:
\[dp(i,j)=dp(i-1,j)+dp(i-1,j-1)\times(i-1) \]直接 \(O(n^2)\) 转移即可。
-
\(type=2\):
事实上本题的难点在这。我们先转化一下,把需要操作的数改为不需要操作的数,此时会发现不需要操作的数就是前缀最大值所在位置。这启发我们建出笛卡尔树,而前缀最大值个数就是左链上的节点个数。
考虑将一个数从开头放到结尾对笛卡尔树的影响是什么,事实上就是把左链最下面的节点放到根节点的右子树,然后把这个节点的右子树接到原来的父亲下面。所以实际上对于一棵笛卡尔树,其最多的不需要操作的数的个数就是走到某个节点过程中往左走的次数。
那么我们考虑对笛卡尔树 dp,先钦定 \(n\) 为根,且它只有左子树,这样圆排列就可以转化为排列了。设 \(dp(i,j)\) 表示 \(i\) 个点构成的笛卡尔树,最多的不需要操作的数的个数为 \(j\) 的方案数。容易得到转移方程:
\[dp(i,\max(p+1,q))=\sum_{j=0}^{i-1} \binom{i-1}{j}\times dp(j,p)\times dp(i-j-1,q) \]直接转移是 \(O(n^4)\) 的,无法通过,不过容易用前缀和优化至 \(O(n^3)\)。
E CF1644F Basis
首先我们先看第一个操作 \(F\),这个操作表明对于一个数组,如果除了最后一个连续段以外的所有连续段长度的 \(\gcd\) 大于 \(1\),那么它就可以被别的数组表示。于是我们希望求出所有 \(\gcd=1\) 的数组作为构造出的数组。同时由于 \(G\) 操作的存在,我们枚举出连续段之后只需要分组即可,因为不管以什么顺序填进去都是同构的。
那么设 \(f(i)\) 表示 \(\gcd=i\) 的方案数,\(g(i)\) 表示 \(i\mid \gcd\) 的方案数,由莫比乌斯反演可得:
那么答案就是 \(f(1)=\sum \mu(d)g(d)\)。现在考虑 \(g(d)\) 怎么求,我们把 \(n\) 每 \(d\) 个划分为一段,最后一段看做补齐,那么总段数就是 \(\lceil \tfrac{n}{d}\rceil\)。只要每段的数字一样就是合法的方案,那么考虑枚举把这些段分成多少组,用第二类斯特林数计算其方案数即可。最后的式子为:
注意这里不枚举 \(i=1\) 是因为所有数字都相同的情况就只有一个连续段了,而这种情况我们不考虑。那么现在考虑计算这个式子的值。我们每次要求一行上斯特林数的前缀和,其实可以直接 NTT 暴力卷积做,复杂度大概是 \(O(\sum \lceil \tfrac{n}{i}\rceil \log \lceil \tfrac{n}{i}\rceil)=O(n\log ^2 n)\) 的,足够通过了。
F CF1553I Stairs
首先根据给出的 \(a_i\) 我们是可以很容易的求出每一个值域连续段的长度的,设总共 \(m\) 个连续段,长度分别为 \(b_1,b_2,\cdots, b_m\)。现在我们只需要将这些连续段拼成一个序列即可,此时的限制条件是我们不能把两个连续段拼成首尾相接的同一个,否则的话原来的值应该会更大。考虑容斥解决,令 \(F(i)\) 表示恰有 \(i\) 个不合法位置的方案数,\(G(i)\) 表示钦定 \(i\) 个位置不合法的方案数,由二项式反演可得:
我们要求的就是 \(F(0)\)。现在考虑 \(G(i)\) 怎么求,由于至少有 \(i\) 个位置不合法,那么我们一定将这 \(m\) 个连续段分成了 \(m-i\) 个首尾相接的部分,所以设 \(f_i\) 表示将所有连续段划分为 \(i\) 个部分的方案数,\(G(i)\) 就应该等于 \(\sum (m-i)! f_{m-i}\)。
现在考虑 \(f\) 怎么求,显然考虑 dp。设 \(dp(i,j)\) 表示将前 \(i\) 个连续段分成 \(j\) 个部分的方案数,转移的时候枚举上一个连续段的结尾 \(k\),分类讨论一下这个部分的长度是不是 \(1\),如果是的话转移系数就会少一个 \(2\)。
- 如果 \(k=i-1\) 且 \(len_i=1\),那么 \(dp(i,j)\gets dp(k,j-1)\)。
- 否则 \(dp(i,j)\gets dp(k,j-1)\times 2\)。
重新整理一下可以得到转移方程:
显然我们可以前缀和优化至 \(O(n^2)\),令 \(s(i,j)=\sum\limits_{k=0}^{i} dp(i,j)\) 即可。不过此时我们似乎无法进一步优化了。观察发现转移中的系数都比较简单,且和 \(j\) 无关,那么考虑写出 \(dp\) 和 \(s\) 的生成函数,然后利用矩阵转移。
令 \(Dp_i(x)=\sum dp(i,j) x^j\),\(S_i(x)=\sum s(i,j) x^j\),则转移可以写作:
那么现在我们要求的是 \(Dp_m(x)\),也就是将 \(m\) 个矩阵相乘。显然可以利用分治 NTT 求解,复杂度可以做到 \(O(n\log^2 n)\),可以通过。
G CF773F Test Data Generation
首先分析一下两种解法错误的条件,第一个要求 \(n\) 为奇数,第二个要求 \(a_n\) 和 \(a_n / g\) 的奇偶性不同,那么也就是 \(a_n\) 为偶数且 \(a_n/g\) 为奇数。
考虑先枚举项数 \(n\),然后枚举 \(a_n\) 中含有的 \(2\) 的数量 \(k\),那么现在所有数都要是 \(2^k\) 的倍数。设 \(b_i=\tfrac{a_i}{2^k}\),那么 \(b_i\) 的取值范围应该是 \([1,\lfloor\frac{max_a}{2^k}\rfloor]\),并且我们还需要保证 \(b_n\) 为奇数。
考虑 dp,设 \(f_p(a,n)\) 表示在 \([1,a]\) 中选出 \(n\) 个数,最后一个数的奇偶性是 \(p\) 的方案数。由于 \(a\) 的范围过大,所以我们肯定需要分治或者倍增求这个值。那么这样的话我们就需要求出 \(f_p(a,n),f_p(a+1,n)\) 以及 \(f_p(2a,n)\) 之间的关系才能转移,分析可得如下转移式:
-
\(f_p(a+1,n)=f_p(a,n)+[(a+1)\bmod 2=p](f_0(a,n-1)+f_1(a,n-1)+[n=1])\)。
这个转移式的意义是:从 \([1,a+1]\) 中选出 \(n\) 个数,要么所有数都在 \([1,a]\) 范围内,要么最后一个数是 \(a+1\),前面所有数在 \([1,a]\) 范围内。注意我们的所有 \(f\) 中都不考虑 \(n=0\) 的情况,因此还需要特判 \(n=1\) 的情况。
-
\(f_p(2a,n)=f_p(a,n)+\sum\limits_{i=0}^n (f_0(a,i)+f_1(a,i)+[i=0])\times f_{p\oplus [a\bmod 2]}(a,n-i)\)。
这个转移式的意义是:从 \([1,2a]\) 中选出 \(n\) 个数,要么所有数都在 \([1,a]\) 范围内,要么前面一部分在 \([1,a]\) 范围内。那么枚举前面这部分数的个数 \(i\),然后对于剩下的 \(n-i\) 个数,先整体减掉 \(a\),这样的话它们的值域也落到 \([1,a]\) 范围内了。注意仍需要特判 \(i=0\) 的情况。
发现转移系数非常简单且和 \(n\) 无关,考虑写成生成函数的形式。令 \(F_p(a)=\sum f_p(a,i) x^i\),则上述转移式可以写成:
- \(F_p(a+1)=F_p(a)+[(a+1)\bmod 2=p]\times x(F_0(a)+F_1(a)+1)\)。
- \(F_p(2a)=F_p(a)+(F_0(a)+F_1(a)+1)\times F_{p\oplus [a\bmod 2]}(a)\)。
这样的话利用多项式乘法,我们可以在 \(O(n\log n)\) 的时间内实现转移。所以总复杂度是 \(O(n\log n\log a)\) 的。然后考虑答案,我们需要对每一个 \(\lfloor\frac{max_a}{2^k}\rfloor\) 求一遍和,显然在分治过程中我们一定会经过所有的值,所以在分治的时候直接算一下答案即可,复杂度不变。
最后注意这个题的模数是任意模数,不能直接用 NTT 做多项式乘法。