推式子的做题记录
「LOJ#3399」Communication Network
首先列出式子,\(ans=\sum\limits_{T_2}|T_1\cap T_2| 2^{T_1\cap T_2}\)
注意到有 \(f(S)=\sum\limits_{T\subseteq S}\sum\limits_{T'\subseteq T}(-1)^{T-T'}f(T')\)
证明可考虑计算每个 \(T'\) 的贡献,由于 \(T'\subseteq T\subseteq S\),\(T\) 必然是 \(T'\) 与 \(S-T'\) 的某个子集的并,于是我们尝试枚举这个子集的大小,可得 \(T'\) 在对这个柿子结果的贡献为 \(f(T')\sum\limits_{i=0}^{|S-T'|}\binom{|S-T'|}{i}(-1)^i=0^{|S-T'|}·f(T')\),因此只有当 \(T'=S\) 时对结果产生 \(f(T')\) 的贡献,其余 \(T'\) 的贡献均为 \(0\),得证。
记 \(f(S)=|S|·2^{|S|}\),那么:
发现,\(\sum\limits_{S\in T_2}1\) 就是包含 \(S\) 当中边的生成树个数,于是题目要求的就是对于所有边集 \(S\),包含 \(S\) 的生成树个数乘上 \(S\) 的大小之和。
根据结论:包含 \(S\) 的生成树个数就是 \(n^{r-2}\prod\limits_{i=1}^r a_i\),其中 \(r\) 为 \(S\) 中的边所形成的连通块个数,\(a_1,a_2,\cdots,a_r\) 为这 \(r\) 个连通块的大小。
于是答案可进一步写成:
此时这玩意儿的组合意义就异常明显了:选择一个边集将这棵树分成若干个连通块,再从每个连通块中选择一个点,产生 \(n\) 的乘积贡献,最后从选定的边集中选择一条边,球所有选法的贡献之和。
这样就可以 DP 了,\(f_{u,0/1,0/1}\) 表示确定了以 \(u\) 为根的子树内连通块的划分情况,\(u\) 所在的连通块是否选择了点,\(u\) 子树内是否有边被选择的方案数,树上背包转移即可。
时间复杂度 \(\mathcal O(n)\)。
$\ \ $
P5900 无标号无根树计数
设 \(n\) 个点的无标号有根树有 \(f_n\) 个,对应的生成函数为 \(F(x)\)。
发现去掉根之后变成了点总和为 \(n-1\) 个的独立的树,是背包,所以可以写出式子:
改写一下:
两边同时取对数把乘改成加:
两边同时求导:
同乘 \(xF(x)\) 去分母:
从生成函数考虑回答案:
(发现前面是求导完再乘上 \(x\),后面是两个多项式相乘,其实是卷积,所以把系数比 \(n\) 小的项给整过去即可。)
因为有:
代入原式得:
设 \(g_n = \sum_{d|n} d \cdot f_d\),有:
这就是一个类似卷积的形式,考虑用分治 \(\text{FFT}\) 优化。
在正常的分治过程中,我们需要 \(f(l)\sim f(mid),g(0)\sim g(r-l)\) 计算贡献。但是在这里所有的 \(g\) 都需要知道比它小的 \(f\) 才能计算。
当分治区间的 \(l=1\) 时,\(g\) 的贡献不能完全计算,所以就先不计算这部分的贡献,改为在计算出一段 \(g\) 后卷积两次来完整计算左区间的贡献(一遍 \(f\) 一遍 \(g\))。
现在已经求出了 \(n\) 个点的无标号有根树的数量,考虑使用容斥转化出为标号无根树的数量。
(不知道为什么我这么难写)
现在已经求出了 \(n\) 个点的无标号有根树的数量,考虑使用容斥转化出为标号无根树的数量。
因为一棵树的重心非常少并且可以用子树大小来描述,那么就使用容斥去掉所有根不为重心的子树,具体来说就是枚举有哪些树的根包含“一个子树的大小大于整棵树大小的一半”就可以解决了。
实际实现的时候考虑枚举断掉原来树的一条中心边来处理,假设 \(h_n\) 为 \(n\) 的无标号无根树的数量。
因为偶数个节点的树可能有两个重心,枚举判掉即可。
那么这个东西的中间的部分很明显是一个卷积,\(\mathcal O(n\log n)\) 求出来然后 \(O(n)\) 就可以求 \(h_n\)。
总复杂度\(\mathcal O(n\log n)\)。
$ \ \ $
P6598 烷烃计数
就是 \(n\) 个点的每个点的度数个数 \(≤4\) 的无标号无根树计数。
先改成除根节点外每个点的子节点个数 \(≤3\),根节点的子节点个数 \(≤4\) 的无标号有根树计数。
还是用无标号无根树计数的处理方法:钦定根为重心,减掉不合法的方案数。
其实只要特别考虑根节点就可以了,设所有节点度数不超过 \(4\) 的无标号无根树的生成函数为 \(P(x)\)。
使用 Burnside 引理和 Polya 定理(括号里的数字代表每个循环的大小):
$\ \ $
P3312 [SDOI2014] 数表
啊↑
首先这个东西某一行某一列本质上是 \(\sigma(\gcd(i,j))\) 所以先考虑整体能不能化简。
令 \(n<m\) 有:
把 \(\gcd(i,j)\) 挪出来,枚举约数:
套路挪到外面去:
直接变成:
令 \(dt=T\) 更换枚举顺序就变成:
设 $g(T) = \sum_{d|T} \sigma(d) \mu(\frac T d) $,可以发现当 \(\sigma(d) \leq a\) 时才会对答案有贡献,考虑离线,按照 \(a\) 排序进行更新。
当更新到某个 \(d\) 时,发现所有的 \(d | T\) 的 \(g(T)\) 都要更新,考虑枚举倍数更新。
发现每次查询答案的时候都要用到一个区间的所有 \(g(T)\) 的值,需要查询区间和。
考虑用树状数组维护。
因为更新时有 \(\sum_{x=1}^n \frac 1 x \approx \ln(n) \),查询时需要在外面套一个数论分块,所以时间复杂度约为 \(\mathcal O( n \log^2 n + q \sqrt n \log n ) \)。
$ \ \ $
5860 最长上升区间
首先可以拆分贡献为:对每个 \(L\),求存在上升区间长度不小于 \(L\) 的方案数。
其反面为:“所有长度为 \(L\) 的子区间均不上升”。依容斥原理,只需对于全体选择若干个长度为 \(L\) 的上升区间的方案,求它们的容斥系数和即可统计。
考虑如果两段上升区间相交,那么可以直接合并。全部合并后,形成若干段独立的上升区间。因此,问题可转化并分为两部分:
-
求一个区间 \([l,r]\) 上升的方案数。
-
求用长度为 \(L\) 的区间来覆盖区间 \([l,r]\)(可以交叉)的所有方案的容斥系数和。
首先处理第一个问题。在固定右端点 \(R\) 的情况下,记 \(f(i,x)\) 表示第 \(i\) 个数取成 \(x\) 所能得到得上升子序列数。又记 \(g(i,x)=\sum^{M_i}_{y=x}f(i,y)\),则 \(f(i,x)=g(i+1,x+1)\)。因此可得 \(g(i,x)=\sum^{M_i}_{y=x}g(i+1,x+1)\) 我们需要维护两个操作:向前平移、求后缀和。
发现可以将 \(g(i,x)\) 表示为 \(\sum_{k≥0} A^i_k \frac{x^{\overline k}}{k!}\) 的形式,轻松递推。
然后处理第二个问题。设 \(h_L(n)\) 表示用长度为 \(L\) 的区间交叉覆盖长度为 \(n\) 的区间所有方案的容斥系数和。那么 \(h_L(L)=1\), 且有 \(h_L(n)=−\sum^{n−1}_{i=n−L+1}h_L(i)\)。
最后只需要枚举 \(L\) 并做一个简单的递推来合并以上区间的容斥系数和。
$\ \ $
AGC053C
考虑 \(2N\) 所在的那一堆,记为 \(B\),则拿空的一定是 \(A\)。
思考 \(B\) 会被拿多少个,发现 \(A\) 中的某个数想要消除掉则要把右边离它最近的 \(B\) 中的比它大的数给拉过来(在左边就顺其自然),记所有 \(A_i\) 中 \(A_i<B_j\) 且 \(j\) 最小的 \(B_j\) 有 \(t=j-i\),则操作次数为 \(n+\max\{t\}\)。
计算期望,记 \(P(d)\) 为总操作次数 \(\leq n+d\) 的概率,则答案为 \(\sum_{i=0}^{n-1} (P(i)-P(i-1))(n+i)\),且有 \(P(n-1)=1\)。
考虑计算 \(P(d)\),令 \(2N\) 在 \(B\) 内,则答案小于 \(n+d\) 当且仅当对于任何 \(i≥1\),\(B_1,B_2,⋯ ,B_{min{i+d,n}}\) 中存在一个值大于 \(A_i\)。
所以有:
预处理奇偶数的前缀积即可。
$\ \ $
[WC2021]斐波那契
首先我们要知道模 \(n\) 意义下的斐波那契数列的循环节长度 \(\mathcal O(n)\),才能考虑后面的事。
考虑题意,记 \(f_n\) 为斐波那契数列的第 \(n\) 项,那么问题就相当于 \(a f_{n-1} + b f_n \equiv 0 (\bmod m)\),求 \(n\)。
考虑把 \(a,b\) 放到一边,\(f_{n-1} , f_n\) 放一起,发现有逆元才能做除法,要求互质。
首先考虑 \(d=\gcd(a,b,m)\),将 \(a,b,m\) 分别除以 \(d\) 后同余方程等价(相当于去掉了一个完全没有用的公因数)。记新的方程为 \(a' f_{n-1} + b' f_n \equiv 0 (\bmod m')\),发现这个时候无法保证两两互质。
变成 \(a' f_{n-1} \equiv - b' f_n (\bmod m')\)
因为斐波那契数列有 $f_{n-1} \perp f_n $,想要保证等式两边相同,那么两边的贡献也得相同.
所以可以保证有 \(\gcd(f_n,m')=\gcd(a',m')=p\) 以及 \(\gcd(f_{n-1},m')=\gcd(-b',m')=q\)。
这样两边与 \(m'\) 的公约数都有且仅有 \(p\) 和 \(q\),把两边同时除以 \(pq\) 就得到了互质的的同余方程。
变成了 $ \frac{q}{p} \cdot \frac{a'}{-b'} \equiv \frac{q}{p} \cdot \frac{f_n}{f_{n-1}} (\bmod \frac{m'}{pq}) $
在某组 \(a,b\) 的询问下,我们根据对应的 \((p,q,\frac{f_n}{f_{n-1}} \bmod \frac{m'}{pq})\) 三元组找到事先预处理好,储存在 map 里面的答案输出就行。
在预处理的时候,先枚举约数,然后根据模意义下只有线性个的 \(f_n\) 和 \(f_{n-1}\) 来处理出对应的 \(p\) 和 \(q\)。总复杂度约为 \(\mathcal O(\sigma(m) \log m)\)

浙公网安备 33010602011771号