LWLAymh的备忘录

混乱节拍拼凑出血肉喧嚷

Here's something encrypted, password is required to continue reading.
阅读全文 »

高数基础补档

复数相关

棣莫弗定理:\(( cos \theta + i \sin \theta )^n = \cos ( n \theta ) + i \sin ( n \theta )\).

欧拉公式:\(e^{ i \pi } = - 1\).

也就是\(e^{ 2 i \pi } = 1\),同时又有\(e^{ i \theta } = cos \theta + i · sin \theta\),证明直接使用泰勒展开.

单位根:对于\(x^n = 1\),我们会有\(n\)个根,设第\(k\)个根为\(\omega_n^k\).那么我们有:\(\omega_n^k = e^{ 2 \pi \frac{ k }{ n } i } = cos ( 2 \pi \frac{ k }{ n } ) + i · sin ( 2 \pi \frac{ k }{ n } )\).

单位根有以下性质:

  1. 折半引理:\(\omega_{ 2 n }^{ 2 k } = \omega_n^k \\\),由我们上面推导的通项公式即可证明.

  2. 消去引理:\(\omega_n^{ k + \frac{ n }{ 2 } } = - \omega_n^k \\\),同样使用通项,运用三角恒等变换可证明.

分圆多项式

上复平面,设\(S_k = ( \cos \frac{ 2 k \pi }{ n } , \sin \frac{ 2 k \pi }{ n } )\),也就是\(z_k = \cos \frac{ 2 k \pi }{ n } + i \sin \frac{ 2 k \pi }{ n }\)是方程\(z^n - 1 = 0\)的复根.我们把这个方程写开:

\[ z^n - 1 = ( z - 1 ) ( z^{ n - 1 } + z^{ n - 2 } + \cdots + 1 ) = 0 \]

不难发现\(z = 1\)是平凡解.

我们不妨定义\(f ( x ) = \prod_{ k = 1 }^n ( 1 + X^k ) = \sum_{ k \geq 0 } a_k X^k\),事实上我们有:

\[ \begin{aligned} \frac{ 1 }{ n } \sum_{ j = 1 }^n f ( \omega_n^j ) & = \frac{ 1 }{ n } \sum_{ j = 1 }^n \sum_{ k \geq 0 } a_k \omega^{ kj }_n \\ & = \frac{ 1 }{ n } \sum_{ k \geq 0 } a_k \sum_{ j = 1 }^n \omega_{ n }^{ kj } \\ & = \sum_{ j \geq 0 } a_{ jn } + \frac{ 1 }{ n } \sum_{ k \geq 0 , n \nmid k } a_k \frac{ 1 - \omega^{ nj }_n }{ 1 - \omega^{ k }_n } \omega_{ n }^j \\ & = \sum_{ j \geq 0 } a_{ jn } \end{aligned} \]

事实上,我们令\(d = \frac{ n }{ \gcd ( j , n ) }\),容易发现\(f ( \omega_n^j ) = ( \prod_{ k = 1 }^d ( 1 + \omega_n^{ kj } ) )^{ \frac{ n }{ d } }\),又容易发现\(n | jd\).

接下来观察\(X^d - 1 = \prod_{ k = 1 }^d ( X - \omega_{ n }^{ kj } )\),带入\(X = - 1\)得到\(f ( \omega_n^j ) = \begin{cases}2^{ \frac{ n }{ d } } & d \in \text{ odd } \\ 0 & d \in \text{ even }\end{cases}\).

接下来考虑拿到\(\sum_{ j } a_{ jn }\),只需求\(\frac{ 1 }{ n } \sum_{ j = 1 }^n f ( \omega_n^j ) = \frac{ 1 }{ n } \sum_{ d \in \text{ odd } , \gcd ( j , n ) = \frac{ n }{ d } } 2^{ \frac{ n }{ d } } = \frac{ 1 }{ n } \sum_{ d \in \text{ odd } } \varphi ( d ) 2^{ \frac{ n }{ d } }\).

Example(尺规做正n边形问题)

碰瓷高斯问题.

一步一步来.根据尺规作图理论:尺规作图只可以实现\(+ , - , \times , \div , \sqrt[2]{ }\)五种操作.而对于正\(n\)边形,显然只要我们能将\(\cos \frac{ 2 \pi }{ n }\)用只含上述五种操作和若干整数表示出来,那就一定可行.

正五边形问题

观察正五边形在复平面上的图像,注意到有两对点互为共轭复数,我们令:

\[ \begin{aligned} \sigma_1 & = z_1 + z_4 \\ \sigma_2 & = z_2 + z_3 \end{aligned} \]

不难验证:

\[ \begin{aligned} \sigma_1 + \sigma_2 & = - 1 \\ \sigma_1 \sigma_2 & = - 1 \end{aligned} \]

可以求出复合条件的解,将\(z\)带入又有:

\[ \begin{aligned} \sigma_1 & = 2 \cos \frac{ 2 \pi }{ 5 } \\ \sigma_2 & = 2 \cos \frac{ 4 \pi }{ 5 } \end{aligned} \]

于是我们显然可以求得.

正七边形

类似正五边形,最后会导出三次方程:根中含有三次根号,因此不行.

正n边形

要解决正17边形,只需要解决正n边形,然后令n=17即可.

你问我咋想到的下面的证明?问高斯去.

下面其实用到了ntt知识,但我懒得扔下面了.

先假设\(n \in \mathrm{ prime }\),我们用\(p\)代替\(n\).

我们有\(z_1 = \cos \frac{ 2 \pi }{ p } + i \sin \frac{ 2 \pi }{ p }\),由于其它的\(z\)都可以表示成它的幂,因此我们记\(\varepsilon = z_1\).

我们现在想要这么分组:

\[ \sigma_{ k + 1 } = \sum_{ 1 \leq l \leq p - 1 , f ( l , k ) = 1 } \varepsilon^l \]

泰勒展开

\(f ( x ) = g ( x ) = f ( x_0 ) + \sum_{ k \geq 1 } \frac{ f^{ ( k ) } ( x_0 ) }{ k ! } ( x - x_0 )^k \\\).\(x_0 = 0\)的时候是麦克劳林级数.

麦克劳林展开是生成函数的基础,我们所谓的生成函数的封闭形式其实就是麦克劳林展开的逆运算(可能也不能完全等价,但笔者能力不够,暂且这么理解).

离散傅里叶变换

考虑如何将一个交换群以一个函数(未必是同态)映射到复数,则这个东西天然对\(\mathbb{C}\)形成线性空间且维度为\(|G|\).

结构定理首先给出\(G\cong \mathbb{Z}_{n_1}\times \cdots\times \mathbb{Z}_{n_k}\),考虑映射\(X_a(x)\),其固定一个\(a:(a_1,\cdots,a_k)\),而将一个\(x:(x_1,\cdots,x_k)\)映射到\(\omega_{n_1}^{a_1x_1}\cdots \omega_{n_k}^{a_kx_k}\).

现在考虑这个映射本身所组成的交换群\(\{X_a\}\),容易发现以下性质:

  1. \(X_aX_b=X_{a+b}\).
  2. \(\bar X_a=X_{-a}\).
  3. \(X_{a}(b)=X_{b}(a)\).
  4. \(\sum_x X_a(x)=\begin{cases}|G|&a=0\\0&\text{otherwise}\end{cases}\)

考虑在上面的复内积\(\langle X_a,X_b\rangle=\sum_x X_a(x)\bar {X_b}(x)=\sum_x X_{a-b}(x)\).根据(3),这显然是一组正交基.从而任何一个\(f:G\to \mathbb{C}\)都可以写作\(\sum \hat f(b)X_b\)的形式,而且\(\hat f(b)=\frac{1}{n}\langle f,X_b\rangle\),容易见到这里\(\hat f(b)\in \mathbb{C}\),从而其实\(\hat f\)也是一个\(G\to \mathbb{C}\)的函数.那如果拿它来做内积会怎么样呢?请看: \[ \begin{aligned} \sum_b \hat f(b)\bar{X}_a(b)&=\sum_b\sum_x \frac{1}{n}f(x)X_{-b}(x)X_{-a}(b)\\ &=\sum_b\sum_x \frac{1}{n}f(x)X_{-b}(x)X_{-b}(a)\\ &=\sum_b\sum_x \frac{1}{n}f(x)X_{-b}(a+x)\\ &=\sum_x \frac{1}{n}f(x)\sum_bX_{-(a+x)}(b)\\ &=f(-a) \end{aligned} \] 接下来定义卷积\((f*g)(x)=\sum_{y}f(y)g(x-y)\).

还是应该再思考一下两者的地位,见到:

  1. \(n\Vert \hat f\Vert^2=\Vert f\Vert^2\).
  2. \(\widehat{cf}=c\hat f\).
  3. \(\widehat{f+g}=\hat f+\hat g\)
  4. \(\widehat{fg}=\hat f*\hat g\).
  5. \(\widehat{f*g}=n\sdot \hat f\sdot \hat g\).

考虑(1),显然\(\Vert f\Vert^2=n\sum_x (\hat f(x))^2\).

(2)(3)显然.

对于(4): \[ \widehat{fg}(x)=\frac{1}{n}\langle fg,X_x\rangle \]

Example

考虑Bool函数\(\{0,1\}^n\to \{0,1\}\).为了使用我们上面的技术,我们将其写作\(\mathbb{Z}_2^n\to \{1,-1\}\).

多项式

多项式基础

点值表示法和系数表示法

代数基本定理:一个\(n - 1\)次方程在复数域上有且只有\(n - 1\)个根.

定理:一个\(n - 1\)次多项式在\(n\)个不同点的取值唯一确定了该多项式.

证明:考虑反证法,假设命题不成立,则存在两个\(n - 1\)次多项式\(A ( x )\)\(B ( x )\)且有\(\forall i \in [ 0 , n - 1 ] , A ( x_i ) = B ( x_i ) \\\).

\(C ( x ) = A ( x ) - B ( x )\),那么\(C ( x )\)至多是一个\(n - 1\)次多项式且\(\forall i \in [ 0 , n - 1 ] , C ( x_i ) = 0 \\\),也就是\(C ( x )\)\(n\)个根,与代数基本定理不符合.

由上面的内容,多项式有点值表示法和系数表示法两种:

系数表示法:\(A ( x ) = \sum_{ i = 0 }^{ n - 1 } a_i x^i \\\).

点值表示法:\(y_i = \sum_{ j = 0 }^{ n - 1 } a_j x_i^j \\\).

已知多项式点值表示法求系数表示法的过程被称为插值.

拉格朗日插值

构造多项式\(\sum_{ i = 0 }^{ n - 1 } y_i ( \prod_{ j = 0 \land j \ne i }^{ n - 1 } \frac{ x - x_j }{ x_i - x_j } ) \\\).显然当\(x = x_i\)时,该多项式的答案为\(y_i\).

另外,如果\(x_i = i\),不难发现这个式子可以写成:

\[ \begin{aligned} & \sum_{ i = 1 }^{ n } y_i ( \prod_{ j = 1 \land j \ne i }^{ n } \frac{ x - x_j }{ x_i - x_j } ) \\ \\ = & \sum_{ i = 1 }^n y_i ( \prod_{ j = 1 \land j \ne i }^n \cfrac{ x - j }{ i - j } ) \\ = & \sum_{ i = 1 }^n y_i ( - 1 )^{ n - i } ( \cfrac{ 1 }{ ( i - 1 ) ! ( n - i ) ! } \prod_{ j = 1 , j \ne i }^{ n } ( x - j ) ) \end{aligned} \]

多项式运算

考虑两个多项式相乘,如果我们已知他们的点值表示法,显然可以直接相乘.

这为我们提供了一种思路:先将系数表示法转化为点值表示法,进行相乘之后再转化回系数表示法.

这引出以FFT为代表的多项式乘法,并拓展到了多种多项式运算.

多项式乘法

快速傅里叶变换(FFT)
DFT

\(n\)次单位根(默认\(n\)是二的整次幂,如果少了的话补零,设\(n = 2^w\))分别带入\(A ( x )\)得到点值向量\(A ( \omega_n^k ) \\\).

如果朴素带入,复杂度显然不可接受.

考虑:

$$ \[\begin{aligned} A ( x ) & = \sum_{ i = 0 }^{ n - 1 } a_i x^i \\ & = \sum_{ i = 2 k , k \in \mathbb{ N } }^{ n - 2 } a_i x^i + \sum_{ i = 2 k + 1 , k \in \mathbb{ N } }^{ n - 1 } a_i x^i \\ & = \sum_{ i = 2 k , k \in \mathbb{ N } }^{ n - 2 } a_i x^{ 2 k } + x \sum_{ i = 2 k + 1 , k \in \mathbb{ N } }^{ n - 1 } a_i x^{ 2 k } \\ \end{aligned}\]

$$

A_2(x)=_{i=2k+1,k}{n-1}a_ix{k}\\(, 那 么\)A(x)=A_1(x2)+xA_2(x2)\

接下来分类讨论:

\(\forall 0 \leq k \leq \frac{ n }{ 2 } - 1 , k \in \mathbb{ N } \\\),我们有:

$$ \[\begin{aligned} A ( \omega_n^k ) & = A_1 ( \omega_n^{ 2 k } ) + \omega_n^k A_2 ( \omega_n^{ 2 k } ) \\ \end{aligned}\]

$$

根据折半引理:

$$ \[\begin{aligned} A ( \omega_n^k ) & = A_1 ( \omega_{ \frac{ n }{ 2 } }^k ) + \omega_n^k A_2 ( \omega^k_{ \frac{ n }{ 2 } } ) \\ \end{aligned}\]

$$

这样我们处理完了前半部分.

\(\forall \frac{ n }{ 2 } \leq k + \frac{ n }{ 2 } \leq n - 1 , k \in \mathbb{ N } \\\),我们有:

$$ \[\begin{aligned} A ( \omega_n^{ k + \frac{ n }{ 2 } } ) & = A_1 ( \omega_n^{ 2 k + n } ) + \omega_n^{ k + \frac{ n }{ 2 } } A_2 ( \omega_n^{ 2 k + n } ) \\ \end{aligned}\]

$$

根据消去引理:

$$ \[\begin{aligned} A ( \omega_n^{ k + \frac{ n }{ 2 } } ) & = A_1 ( \omega_{ \frac{ n }{ 2 } }^k ) - \omega_n^k A_2 ( \omega_{ \frac{ n }{ 2 } }^k ) \\ \end{aligned}\]

$$

综上,我们可以递归处理\(A_1\)\(A_2\),然后合并得到\(A\)的答案,可以分治.

IDFT

\(A ( \omega_n^k ) = d_k \\\),构造多项式\(F ( x ) = \sum_{ i = 0 }^{ n - 1 } d_i x^i \\\).

我们求出\(F ( x )\)的点值表示,设\(c_k = F ( \omega_n^{ - k } ) \\\),也即:

$$ \[\begin{aligned} c_k & = \sum_{ i = 0 }^{ n - 1 } d_i ( \omega_n^{ - k } )^i \\ & = \sum_{ i = 0 }^{ n - 1 } ( \sum_{ j = 0 }^{ n - 1 } a_j ( \omega_n^i )^j ) ( \omega_n^{ - k } )^i \\ & = \sum_{ j = 0 }^{ n - 1 } a_j \sum_{ i = 0 }^{ n - 1 } ( \omega_n^i )^{ j - k } \\ \end{aligned}\]

$$

\(j = k\)时,显然\(\sum_{ i = 0 }^{ n - 1 } ( \omega_n^i )^{ j - k } = n \\\).

否则根据等比数列求和公式,\(\sum_{ i = 0 }^{ n - 1 } ( \omega_n^i )^{ j - k } = \frac{ \omega^0_n [ ( \omega_n^{ j - k } )^n - 1 ] }{ \omega_n^{ j - k } - 1 } = 0 \\\).

所以\(\sum_{ i = 0 }^{ n - 1 } ( \omega_n^i )^{ j - k } = n [ j = k ] \\\).

那么我们有

a_k=\

写法

递归写法显然.

递归过程中,第\(k\)层相当于在根据数在第\(k\)位的二进制数是\(1\)还是\(0\)来分类.那显然可以求出最后一层的数组,然后向上合并.

(没找到fft的代码,懒得写了,直接用的ntt的,注意快速幂要处理幂为负数的情况).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
inline void init_rev(int limit,int k){
rev[0]=0;
for(int i=1;i<limit;++i){
rev[i]=(rev[i>>1]>>1)|((i&1)<<(k-1));
}
return ;
}
inline void ntt(int limit,ll *a,ll t){//DFT:t=1;IDFT:t=-1
for(int i=0;i<limit;++i){
if(i<rev[i])std::swap(a[i],a[rev[i]]);
}
for(int mid=1;mid<limit;mid=mid<<1){
int n=mid<<1;
ll wn=mpow(gn,t*(mod-1)/n);
for(int i=0;i<limit;i+=n){
ll w=1;
for(int k=0;k<mid;++k,w=w*wn%mod){
ll wakn=w*a[i+k+mid]%mod;
ll ak=a[i+k];
a[i+k]=ak+wakn;Mod(a[i+k]);
a[i+k+mid]=ak-wakn+mod;Mod(a[i+k+mid]);
}
}
}
if(t==-1){
ll inv=mpow(limit,-1);
for(int i=0;i<limit;++i){
a[i]=a[i]*inv%mod;
}
}
return ;
}
快速数论变换(NTT)

由于FFT中的单位根会产生精度误差,因此在膜\(998244353\)意义下,通常会选择NTT来进行多项式乘法.

NTT与FFT的运算过程基本相同,证明过程基本相同,唯一不同的是将单位根改为了原根.

根据上面FFT的证明过程,我们知道,设原根为\(g\),\(g_n = g^{ \frac{ p - 1 }{ n } } \\\),只需要证明原根满足以下条件,就可以进行变换:

  1. \(g_n^n = g_n^0 = 1\)\(\forall 0 \leq i < j < n , g_n^i \ne g_n^j\),证明由原根的性质.

  2. 折半引理:\(g_{ 2 n }^{ 2 k } = g_{ n }^k\),证明显然.

  3. 消去引理:\(g_{ n }^{ k + \frac{ n }{ 2 } } = - g^k_n \\\).由于\(g^{ \frac{ p - 1 }{ 2 } } = - 1\),该结论显然成立.

由上我们证明了,我们完全可以使用\(g_n\)代替\(\omega_n\)进行变换.

另外,注意到\(998244352 = 2^{ 23 } \times 7 \times 17 \\\),而\(2^{ 23 } \approx 8 \times 10^6 \\\).因而,当\(n \leq 8 \times 10^6\)的时候,\(g_n\)可以直接求出.这也是为什么大部分NTT题目都使用\(998244353\)作为模数的原因.

范德蒙德矩阵理解

范德蒙德矩阵形如:

\[ \begin{bmatrix} 1 & \alpha_1 & \cdots & \alpha_1^{ n - 1 } \\ 1 & \alpha_2 & \cdots & \alpha_2^{ n - 1 } \\ \vdots & \vdots & \ddots & \vdots \\ 1 & \alpha_m & \cdots & \alpha_m^{ n - 1 } \end{bmatrix} \in \mathbb{ R }^{ m \times n } \]

如果取单位根,我们有:

\[ \begin{bmatrix} 1 & 1 & \cdots & 1 \\ 1 & \omega_n^1 & \cdots & \omega_2^{ n - 1 } \\ \vdots & \vdots & \ddots & \vdots \\ 1 & \omega_n^{ n - 1 } & \cdots & \omega_n^{ ( n - 1 )^2 } \end{bmatrix} \in \mathbb{ R }^{ n \times n } \]

这就是我们在做FFT(一个线性变换)的时候的变换矩阵.所以我们有:

\[ \begin{bmatrix} 1 & 1 & \cdots & 1 \\ 1 & \omega_n^1 & \cdots & \omega_2^{ n - 1 } \\ \vdots & \vdots & \ddots & \vdots \\ 1 & \omega_n^{ n - 1 } & \cdots & \omega_n^{ ( n - 1 )^2 } \end{bmatrix}^{ - 1 } = \frac{ 1 }{ n } \begin{bmatrix} 1 & 1 & \cdots & 1 \\ 1 & \omega_n^{ - 1 } & \cdots & \omega_2^{ - ( n - 1 ) } \\ \vdots & \vdots & \ddots & \vdots \\ 1 & \omega_n^{ - ( n - 1 ) } & \cdots & \omega_n^{ - ( n - 1 )^2 } \end{bmatrix} \]

分治FFT

给定\(g ( x )\)\(f ( 0 )\),求\(f ( x ) = \sum_{ y = 1 }^x f ( x - y ) g ( y )\),答案对\(998244353\)取膜.

考虑分治,假如我们已经知道了\(f ( x ) , x \in [ 1 , \frac{ n }{ 2 } ]\).那我们可以计算出这段部分对\(f ( y ) , y \in [ \frac{ n }{ 2 } + 1 , n ]\)的贡献.

这显然是一个卷积的形式,我们直接计算\(f\)\(g\)的乘积并贡献上去.

多项式求逆

对于多项式\(P ( x )\),找到\(Q ( x )\)使得\(Q ( x ) P ( x ) \equiv 1 \pmod{ x^{ n } } \\\).显然\(Q ( x )\)是唯一的.

首先不妨设\(n = 2^k \\\).

如果我们已知\(P ( x ) Q_{ k - 1 } ( x ) \equiv 1 \pmod{ x^{ 2^{ k - 1 } } } \\\),同时肯定有\(P ( x ) Q_{ k } ( x ) \equiv 1 \pmod{ x^{ 2^{ k - 1 } } } \\\),相减得到\(Q_k ( x ) - Q_{ k - 1 } ( x ) \equiv 0 \pmod{ x^{ 2^{ k - 1 } } } \\\).

两边平方:

$$ \[\begin{aligned} Q_k^2 ( x ) + Q^2_{ k - 1 } ( x ) - 2 Q_k ( x ) Q_{ k - 1 } ( x ) & \equiv 0 \pmod{ x^{ 2^k } } \\ \end{aligned}\]

$$

两边乘一下\(P ( x )\):

$$ \[\begin{aligned} Q_k ( x ) - 2 Q_{ k - 1 } ( x ) + P ( x ) Q_{ k - 1 }^2 ( x ) & \equiv 0 \pmod{ x^n } \\ Q_k ( x ) & \equiv 2 Q_{ k - 1 } ( x ) - P ( x ) Q_{ k - 1 }^2 ( x ) \pmod{ x^n } \\ \end{aligned}\]

$$

根据主定理,这么做复杂度是\(O ( n \log_2 n )\)的.

同时,多项式求逆可以解决上面提到的分治FFT.我们注意到分治FFT的条件等价于:

\[ \begin{aligned} F ( x ) & \equiv F ( x ) G ( x ) + f_0 \pmod{ x^{ n + 1 } } \\ F ( x ) & = \frac{ f ( 0 ) }{ 1 - G ( x ) } \pmod{ x^{ n + 1 } } \end{aligned} \]

于是可以直接做多项式求逆.

多项式除法

对于\(n\)次多项式\(F ( x )\)\(m\)次多项式\(G ( x )\),找到\(Q ( x ) , R ( x )\)使得\(F ( x ) = G ( x ) Q ( x ) + R ( x ) \\\).

考虑对于\(n\)次多项式\(F ( x )\),令\(F_R ( x ) = x^n F ( \cfrac{ 1 }{ x } )\),如果设\(f_i\)为其\(x^i\)项前的系数,不难发现\(f_R ( i ) = f ( n - i )\).

那么我们有:

\[ \begin{aligned} F ( x ) & = G ( x ) Q ( x ) + R ( x ) \\ F ( \cfrac{ 1 }{ x } ) & = G ( \cfrac{ 1 }{ x } ) Q ( \cfrac{ 1 }{ x } ) + R ( \cfrac{ 1 }{ x } ) \\ x^n F ( \cfrac{ 1 }{ x } ) & = x^m G ( \cfrac{ 1 }{ x } ) x^{ n - m } Q ( \cfrac{ 1 }{ x } ) + x^{ n - m + 1 } x^{ m - 1 } R ( \cfrac{ 1 }{ x } ) \\ F_R ( x ) & = G_R ( x ) Q_R ( x ) + x^{ n - m + 1 } R_R ( x ) \\ F_R ( x ) & \equiv G_R ( x ) Q_R ( x ) \pmod{ x^{ n - m + 1 } } \\ Q_R ( x ) & \equiv F_R ( x ) G_R^{ - 1 } ( x ) \pmod{ x^{ n - m + 1 } } \end{aligned} \]

于是只要做一遍多项式求逆即可求得\(Q ( x )\),再做一遍相减既可以得到\(R ( x )\).

多项式ln

给出\(n - 1\)次多项式\(A ( x )\),求一个多项式\(B ( x )\),满足\(B ( x ) \equiv \ln A ( x )\).

我们有:

$$ \[\begin{aligned} B ( x ) & \equiv \ln A ( x ) \pmod{ x^n } \\ B ' ( x ) & \equiv \cfrac{ A ' ( x ) }{ A ( x ) } \pmod{ nx^{ n - 1 } } \\ B ( x ) & \equiv \int \cfrac{ A ' ( x ) }{ A ( x ) } dx \pmod{ x^n } \\ \end{aligned}\]

$$

另外,考虑中间求导的过程中,其实模数也要相应发生变化,但是由于模数是从更高次变低,而最后积分的时候又要变回来,所以可以直接忽略变化.

定理:在模意义下当且仅当\([ x^0 ] f ( x ) = 1\)的时候,\(f ( x )\)有对数多项式.

我们对最后再做一步:

$$ \[\begin{aligned} B ( x ) & \equiv \int_0^x \cfrac{ A ' ( t ) }{ A ( t ) } dt + B ( 0 ) \pmod{ x^n } \\ \end{aligned}\]

$$

首先\(B ( 0 ) = \ln A ( 0 ) = \ln a_0\),如果\(a_0 \in \mathbb{ Q } \land a_0 \ne 1\),则\(B ( 0 ) \notin \mathbb{ Q }\),因此不能放到模意义下,自然不存在对数多项式.

\([ x^0 ] f ( x ) = 1\)的时候,\(B ( 0 ) = 0\),因此可以直接求出答案.

牛顿迭代

给定多项式\(G ( x )\),求一个多项式\(F ( x )\)满足\(G ( F ( x ) ) \equiv 0 \pmod{ x^n }\).

首先\(n = 1\)的时候,也就是求\(G ( F ( x ) ) \equiv 0 \pmod{ x }\).这个要根据具体题目具体分析求出.

假设我们已经求出了在\(\bmod x^{ \lceil \frac{ n }{ 2 } \rceil }\)意义下的答案\(F_0 ( x )\),我们考虑在\(F_0 ( x )\)处做泰勒展开:

$$ \[\begin{aligned} G ( F ( x ) ) & = \sum_{ k = 0 }^{ + \infty } \frac{ G^{ ( k ) } ( F_0 ( x ) ) }{ k ! } ( F ( x ) - F_0 ( x ) )^k \equiv 0 \pmod{ x^n } \\ \end{aligned}\]

$$

考虑\(F ( x ) - F_0 ( x )\),由于\(F_0 ( x ) \equiv F ( x ) \pmod{ x^{ \lceil \frac{ n }{ 2 } \rceil } }\),因此,因此\(( F ( x ) - F_0 ( x ) )^2 \equiv 0 \pmod{ x^n }\).

于是我们有:

\[ \begin{aligned} \sum_{ k = 0 }^{ + \infty } \frac{ G^{ ( k ) } ( F_0 ( x ) ) }{ k ! } ( F ( x ) - F_0 ( x ) )^k & \equiv 0 \pmod{ x^n } \\ G ( F_0 ( x ) ) + G ' ( F_0 ( x ) ) ( F ( x ) - F_0 ( x ) ) & \equiv 0 \pmod{ x^n } \\ F ( x ) & \equiv F_0 ( x ) - \frac{ G ( F_0 ( x ) ) }{ G ' ( F_0 ( x ) ) } \pmod{ x^n } \end{aligned} \]

牛顿迭代可以用来证明多项式求逆的式子同样正确.

多项式开方

给定\(h ( x )\),设\(g ( f ( x ) ) = f^2 ( x ) - h ( x )\),求零点.

根据牛顿迭代,有:

\[ f ( x ) \equiv f_0 ( x ) - \frac{ f^2 ( x ) - h ( x ) }{ 2 f_0 ( x ) } \equiv \frac{ f^2 ( x ) + h ( x ) }{ 2 f_0 ( x ) } \pmod{ x^n } \]

还没完,用牛顿迭代前一定要求\(g ( a ) \equiv 0 \pmod{ x^n }\)的解,也就是\([ x^0 ] h ( x )\)的开根,用二次剩余算.

多项式exp

给定\(h ( x )\),设\(g ( f ( x ) ) = \ln f ( x ) - h ( x )\),求零点.

根据牛顿迭代,有:

\[ \begin{aligned} f ( x ) & \equiv f_0 ( x ) - \frac{ \ln f_0 ( x ) - h ( x ) }{ \frac{ 1 }{ f_0 ( x ) } } \pmod{ x^n } \\ & \equiv f_0 ( x ) ( 1 - \ln f_0 ( x ) + h ( x ) ) \pmod{ x^n } \end{aligned} \]

还没完,还需要求\(g ( a ) \equiv 0 \pmod{ x^n }\)的解,注意到存在\(\exp\)当且仅当\([ x^0 ] g ( x ) \equiv 0\),此时\(f ( x ) \equiv 1 \pmod{ x }\).

多项式快速幂

\(\ln\)后求\(\exp\)即可,唯一的问题是为什么指数可以对\(p\)取膜.

我们有一个结论:

\[ f ( x^p ) \equiv f ( x )^p \pmod{ p } \]

这个结论很简单,注意到\(( a + b )^p \equiv a^p + b^p \pmod{ p }\)即可.

而又由于\(n < p\),因此\(f ( x )^p \equiv f ( 0 ) \pmod{ p }\),通常取\(f ( 0 ) = 1\),于是就可以直接对\(p\)取膜.

多项式运算全家桶(重载运算符版)

我们必须指出的一点是,虽然重载运算符很好看,但是大部分情况下还是需要指针传参.例如在这里,由于做\(\exp\)的时候的直接数组传参,会导致\(\exp\)的复杂度退化到\(O ( n \log^2 n )\).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#include<algorithm>
#include<cstring>
#include<cstdio>
#define ll long long
#define qwq 300007
const int mod=998244353;
const int gn=3;
int n;
int rev[qwq];
ll inv[qwq];
struct poly{
ll x[qwq];
int limit,k;
}a;
inline void Mod(ll &x){
if(x>=mod)x-=mod;
if(x<0)x+=mod;
return ;
}
inline ll mpow(ll x,ll k){
if(k<0)k+=mod-1;
ll ans=1;
for(;k;k=k>>1,x=x*x%mod){
if(k&1)ans=ans*x%mod;
}
return ans;
}
inline ll get_inv(int x){
if(x>qwq-7)return mpow(x,mod-2);
if(inv[x])return inv[x];
else return inv[x]=mpow(x,mod-2);
}
inline void init_rev(int limit,int k){
for(int i=1;i<limit;++i){
rev[i]=(rev[i>>1]>>1)|((i&1)<<(k-1));
}
return ;
}
inline void ntt(poly *a,int t){
init_rev((a->limit),(a->k));
for(int i=0;i<(a->limit);++i){
if(rev[i]>i)std::swap(a->x[i],a->x[rev[i]]);
}
for(int mid=1;mid<(a->limit);mid=mid<<1){
int n=mid<<1;
ll wn=mpow(gn,t*(mod-1)/n);
for(int i=0;i<(a->limit);i+=n){
ll w=1;
for(int k=0;k<mid;++k,w=w*wn%mod){
ll wakn=w*(a->x[i+k+mid])%mod;
ll ak=(a->x[i+k]);
a->x[i+k]=ak+wakn;Mod(a->x[i+k]);
a->x[i+k+mid]=ak-wakn;Mod(a->x[i+k+mid]);
}
}
}
if(t==-1){
ll inv=get_inv(a->limit);
for(int i=0;i<a->limit;++i){
a->x[i]=(a->x[i])*inv%mod;
}
}
return ;
}
inline poly operator %(poly x,int k){//对x^{2^k}取膜
for(int i=(1<<k);i<x.limit;++i)x.x[i]=0;
x.k=k;
x.limit=1<<k;
return x;
}
inline poly operator +(poly x,poly y){
x.limit=std::max(x.limit,y.limit);
x.k=std::max(x.k,y.k);
for(int i=0;i<x.limit;++i){
x.x[i]+=y.x[i];Mod(x.x[i]);
}
return x;
}
inline poly operator -(poly x,poly y){
x.limit=std::max(x.limit,y.limit);
x.k=std::max(x.k,y.k);
for(int i=0;i<x.limit;++i){
x.x[i]-=y.x[i];Mod(x.x[i]);
}
return x;
}
inline poly operator*(ll x,poly y){
for(int i=0;i<y.limit;++i){
y.x[i]=x*y.x[i]%mod;
}
return y;
}
inline poly operator *(poly x,poly y){
x.limit=std::max(x.limit,y.limit)<<1;
x.k=std::max(x.k,y.k)+1;
y.limit=x.limit;y.k=x.k;
ntt(&x,1);ntt(&y,1);
for(int i=0;i<x.limit;++i){
x.x[i]=x.x[i]*y.x[i]%mod;
}
ntt(&x,-1);
return x;
}
poly q_inv,tmp_inv;
inline poly invpoly(poly x){
for(int i=0;i<(x.limit<<1);++i){
q_inv.x[i]=tmp_inv.x[i]=0;
}
q_inv.x[0]=mpow(x.x[0],-1);q_inv.limit=1,q_inv.k=0;
for(int lim=2,k=1;lim<=x.limit;lim=lim<<1,++k){
for(int i=0;i<lim;++i){
tmp_inv.x[i]=x.x[i];
}
tmp_inv.limit=q_inv.limit=lim;
tmp_inv.k=q_inv.k=k;
q_inv=2ll*q_inv-q_inv*q_inv%k*tmp_inv%k;
}
q_inv.limit=x.limit;q_inv.k=x.k;
return q_inv;
}
inline poly operator /(poly x,poly y){
int lim=x.limit,k=x.k;
x=x*invpoly(y);
for(int i=lim;i<x.limit;++i){
x.x[i]=0;
}
x.limit=lim,x.k=k;
return x;
}
inline poly Dpoly(poly x){//求导
for(int i=1;i<x.limit;++i){
x.x[i-1]=x.x[i]*i%mod;
x.x[i]=0;
}
return x;
}
inline poly Spoly(poly x){//积分
for(int i=x.limit-1;i>=0;--i){
x.x[i+1]=x.x[i]*get_inv(i+1)%mod;
x.x[i]=0;
}
return x;
}
inline poly lnpoly(poly x){
if(x.x[0]!=1);//无解
return Spoly(Dpoly(x)/x);
}
poly q_exp,tmp_exp;
inline poly exppoly(poly x){
if(x.x[0]!=0);//无解
for(int i=0;i<(x.limit<<1);++i){
q_exp.x[i]=tmp_exp.x[i]=0;
}
q_exp.x[0]=1;
for(int lim=2,k=1;lim<=x.limit;lim=lim<<1,++k){
for(int i=0;i<lim;++i)tmp_exp.x[i]=x.x[i];
tmp_exp.limit=q_exp.limit=lim;
tmp_exp.k=q_exp.k=k;
q_exp=(q_exp+q_exp*(tmp_exp-lnpoly(q_exp)))%k;
}
return q_exp;
}
poly q_sqrt,tmp_sqrt;
inline poly sqrtpoly(poly x){
if(x.x[0]!=1);//如果不是1要做二次剩余
q_sqrt.x[0]=1;
for(int lim=2,k=1;lim<=x.limit;lim=lim<<1,++k){
for(int i=0;i<lim;++i)tmp_sqrt.x[i]=x.x[i];
tmp_sqrt.limit=q_sqrt.limit=lim;
tmp_sqrt.k=q_sqrt.k=k;
q_sqrt=(q_sqrt*q_sqrt%k+tmp_sqrt)/(2ll*q_sqrt)%k;
}
return q_sqrt;
}
inline poly powpoly(poly x,ll k){
if(x.x[0]!=1);//无解
x=k*lnpoly(x);
return exppoly(x);
}

集合幂级数

集合幂级数形如\(\sum_{ i = 0 }^{ 2^n - 1 } a_i x^i\),其中二进制数\(i\)表示\(\{ 1 , 2 , . . . , n \}\)的一个子集,用\(| i |\)表示该子集大小,等价于对二进制使用的popcount函数.

下述级数如无特别说明均为集合幂级数.

与/或卷积

高维前缀和:\(c_i = \sum_{ j \subseteq i } a_j \\\).

高维后缀和:\(c_i = \sum_{ j \supseteq i } a_j \\\).

上述过程又称快速莫比乌斯变换(FMT).

1
2
3
4
5
6
for(int i=0;i<n;i++)
for(int j=0;j<(1<<n);j++)
if(j&(1<<i)) a[j]+=a[j^(1<<i)];//高维前缀和
for(int i=0;i<n;i++)
for(int j=0;j<(1<<n);j++)
if(j&(1<<i)) a[j^(1<<i)]+=a[j];//高维后缀和

或卷积:\(c_i = \sum_{ j } \sum_{ k } [ j \lor k = i ] a_j b_k \\\).

与卷积:\(c_i = \sum_{ j } \sum_{ k } [ j \land k = i ] a_j b_k \\\).

二者求法类似,考虑如何求\(a\)\(b\)的或卷积:

引理:

\(j , k \subseteq i\),则\(j \lor k \subseteq i\),逆命题同样成立.

\(j , k \supseteq i\),则\(j \land k \supseteq i\),逆命题同样成立.

\(a , b , c\)的高维前缀和分别为\(A , B , C\),我们有:

$$ \[\begin{aligned} A_i B_i & = ( \sum_{ j \subseteq i } a_j ) ( \sum_{ k \subseteq i } b_k ) \\ & = \sum_{ j , k \subseteq i } a_i b_k \\ & = \sum_{ k \lor j \subseteq i } a_i b_k \\ & = C_i \\ \end{aligned}\]

$$

现在考虑已知\(C\)\(c\),本质上是一个反演.注意到\(\sum_{ r \subseteq p } ( - 1 )^{ | r | } = \sum_{ k = 0 }^{ | p | } C_{ | p | }^k ( - 1 )^k = [ p = 0 ] \\\),我们有:

$$ \[\begin{aligned} c ( p ) & = \sum_{ q \subseteq p } [ p - q = 0 ] c ( q ) \\ & = \sum_{ q \subseteq p } \sum_{ r \subseteq ( p - q ) } ( - 1 )^{ | r | } c ( q ) \\ & = \sum_{ r \subseteq p } ( - 1 )^{ | r | } \sum_{ q \subseteq ( p - r ) } c ( q ) \\ & = \sum_{ r \subseteq p } ( - 1 )^{ r } C ( p - r ) \\ & = \sum_{ r \subseteq p } ( - 1 )^{ | p | - | r | } C ( r ) \\ \end{aligned}\]

$$

于是有\(c ( S ) = \sum_{ T \subseteq S } ( - 1 )^{ | S | - | T | } C ( T ) \\\)(实际上就是个差分的过程).

因而做两遍高维前缀和再反推回去即可,复杂度\(O ( 2^n n )\).

与卷积即改为高维后缀和.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
inline void FWT_and(ll *a,ll t,int limit){//FWT:t=1;IFWT:t=-1
for(int mid=1;mid<limit;mid=mid<<1){
int n=mid<<1;
for(int j=0;j<limit;j+=n){
for(int k=0;k<mid;++k){
a[j+k]+=t*a[j+k+mid]%mod;
Mod(a[j+k]);
}
}
}
return ;
}

inline void FWT_or(ll *a,ll t,int limit){//FWT:t=1;IFWT:t=-1
for(int mid=1;mid<limit;mid=mid<<1){
int n=mid<<1;
for(int j=0;j<limit;j+=n){
for(int k=0;k<mid;++k){
a[j+k+mid]+=t*a[j+k]%mod;
Mod(a[j+k+mid]);
}
}
}
return ;
}

异或卷积

异或卷积:\(c_i = \sum_j \sum_k [ j \oplus k = i ] a_j b_k \\\).

引理:\(( i \oplus j ) \land k = ( i \land k ) \oplus ( j \land k )\).

证明的话考虑如果\(k = 0\),二者显然相等;当\(k = 1\)的时候,左右都等价于\(( i \oplus j )\).

快速沃尔什变换(FWT):

定义集合幂级数\(FWT ( a )\),满足\(FWT ( a )_i = \sum_{ j = 0 }^{ 2^n - 1 } ( - 1 )^{ | i \land j | } a_j \\\).

那么有:

$$ \[\begin{aligned} FWT ( c )_i & = \sum_{ j = 0 }^{ 2^n - 1 } ( - 1 )^{ | i \land j | } c_j \\ & = \sum_{ j = 0 }^{ 2^n - 1 } ( - 1 )^{ | i \land j | } \sum_{ k = 0 }^{ 2^n - 1 } \sum_{ l = 0 }^{ 2^n - 1 } [ k \oplus l = j ] a_k b_l \\ & = \sum_{ k = 0 }^{ 2^n - 1 } \sum_{ l = 0 }^{ 2^n - 1 } ( - 1 )^{ | ( k \oplus l ) \land i | } a_k b_l \\ & = \sum_{ k = 0 }^{ 2^n - 1 } \sum_{ l = 0 }^{ 2^n - 1 } ( - 1 )^{ | k \land i | } a_k ( - 1 )^{ | l \land i | } b_l \\ & = FWT ( a )_i FWT ( b )_i \\ \end{aligned}\]

$$

时间复杂度\(O ( 2^n n )\).

逆运算的话考虑实现过程,反向就行.不过可以把过程中乘上的\(\frac{ 1 }{ 2 }\)都提出来乘到最后.

FMT可以看作是FWT在解决与/或卷积时的特例.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
inline void FWT_xor(ll *a,ll t,int limit){//FWT:t=1;IFWT:t=-1
for(int mid=1;mid<limit;mid=mid<<1){
int n=mid<<1;
for(int j=0;j<limit;j+=n){
for(int k=0;k<mid;++k){
ll x=a[j+k],y=a[j+k+mid];
a[j+k]=x+y;Mod(a[j+k]);
a[j+k+mid]=x-y;Mod(a[j+k+mid]);
}
}
}
if(t==-1){
ll inv=mpow(limit,mod-2);
for(int i=0;i<limit;++i)a[i]=a[i]*inv%mod;
}
return ;
}

快速沃尔什变换

线性代数角度

我们来重定义一下所谓的FWT.

首先类比FFT,我们希望存在一个线性变换\(FWT\),使得

  1. \(c_i = \sum_{ j \oplus k } a_j b_k\),则\(FWT ( c ) = FWT ( a ) FWT ( b )\).

  2. 这个线性变换是可逆的.

  3. 做这个线性变换和其逆变换的复杂度都可以接受.

我们设\(FWT ( A )_i = \sum_{ j } w ( i , j ) A_j\),我们想要做的就是构造一组满足上述条件的\(w\).

考虑:

\[ \begin{aligned} FWT ( C )_i & = FWT ( A )_i FWT ( B )_i \\ \sum_{ j } w ( i , j ) C_j & = \sum_{ j , k } w ( i , j ) w ( i , k ) A_j B_k \end{aligned} \]

再考虑:

\[ \begin{aligned} C & = A * B \\ C_i & = \sum_{ k \oplus l = i } A_k B_l \\ \sum_{ j } w ( i , j ) C_j & = \sum_j w ( i , j ) \sum_{ k \oplus l = j } A_k B_l \\ \sum_{ j , k } w ( i , j ) w ( i , k ) A_j B_k & = \sum_j w ( i , j ) \sum_{ k \oplus l = j } A_k B_l \\ \sum_{ j , k } w ( i , j ) w ( i , k ) A_j B_k & = \sum_{ j , k } A_j B_k w ( i , j \oplus k ) \end{aligned} \]

比较两边系数,有\(w ( i , j ) w ( i , k ) = w ( i , j \oplus k )\).只要满足这个条件,我们就能构造出一组满足条件(1)的线性变换.如果这个线性变换对应的矩阵可逆,那么就满足了条件(2).

而由于\(\oplus\)是集合的运算,我们可以对二进制分开考虑.换句话说,如果\(a = \sum_{ i = 0 } a_i 2^i , b = \sum_{ i = 0 } b_i 2^i\),那么\(w ( a , b ) = \prod_{ i = 0 } w ( a_i , b_i )\)一定是满足条件的.

这样我们就可以只求一个\(2 \times 2\)的线性变换矩阵就好.我们接下来将对三种常见的基础位运算(\(\lor , \land , xor ( \oplus )\))分别讨论这个矩阵.我们先来解决第三个问题:如何快速求出\(FWT ( a )\)呢?

考虑和FFT一样折半,令\(i_0\)\(i\)的最高位是否是\(1\),\(i '\)\(i\)去掉最高位后的二进制数字,令\(n = 2^m\)我们有:

\[ \begin{aligned} FWT ( A )_i & = \sum_{ j = 0 }^{ 2^m - 1 } w ( i , j ) A_j \\ & = \sum_{ j = 0 }^{ 2^{ m - 1 } - 1 } w ( i , j ) A_j + \sum_{ j = 2^{ m - 1 } }^{ 2^m - 1 } w ( i , j ) A_j \\ & = w ( i_0 , 0 ) \sum_{ j = 0 }^{ 2^{ m - 1 } - 1 } w ( i ' , j ' ) A_j + w ( i_0 , 1 ) \sum_{ j = 2^{ m - 1 } }^{ 2^m - 1 } w ( i ' , j ' ) A_j \end{aligned} \]

这样就实现了规模减半,复杂度\(O ( mn )\).

下面我们设FWT的变换矩阵为\(\begin{bmatrix}w ( 0 , 0 ) & w ( 0 , 1 ) \\ w ( 1 , 0 ) & w ( 1 , 1 )\end{bmatrix}\).顺便一提,不难发现,最后对整体做的矩阵是这个矩阵的克罗内多积.

或卷积

取矩阵\(\begin{bmatrix}1 & 0 \\ 1 & 1\end{bmatrix}\).其逆矩阵为\(\begin{bmatrix}1 & 0 \\ - 1 & 1\end{bmatrix}\).

与卷积

取矩阵\(\begin{bmatrix}1 & 1 \\ 0 & 1\end{bmatrix}\).其逆矩阵为\(\begin{bmatrix}1 & - 1 \\ 0 & 1\end{bmatrix}\).

异或卷积

取矩阵\(\begin{bmatrix}1 & 1 \\ 1 & - 1\end{bmatrix}\).其逆矩阵为\(\begin{bmatrix}\frac{ 1 }{ 2 } & \frac{ 1 }{ 2 } \\ \frac{ 1 }{ 2 } & - \frac{ 1 }{ 2 }\end{bmatrix}\).

生成函数角度

我们再从生成函数角度理解一下FWT.

我们重新定义幂乘法:\(x^S x^T = x^{ S \oplus T }\),显然幂乘法该满足的性质它都满足.

观察FWT的式子:

\[ \begin{aligned} FWT ( A )_S & = \sum_{ T = 0 }^{ 2^n - 1 } ( - 1 )^{ | S \land T | } a_T \\ IFWT ( A )_S & = \frac{ 1 }{ 2^n } FWT ( A )_S \end{aligned} \]

这等价于:

\[ \begin{aligned} [ x^S ] FWT ( A ) & = \sum_{ T = 0 }^{ 2^n - 1 } ( - 1 )^{ | S \land T | } a_T \\ [ x^S ] IFWT ( A ) & = [ x^S ] \frac{ 1 }{ 2^n } FWT ( A ) \end{aligned} \]

子集卷积

子集卷积:\(c_i = \sum_{ j } \sum_{ k } [ j \land k = \emptyset , j \lor k = i ] a_j b_k \\\).

意识到该卷积与或卷积的差别在于:或卷积会多累加一些\([ j \land k \ne \emptyset ]\)的答案,而\([ j \land k = \phi , j \lor k = i ] = [ | j | + | k | = | i | , j \lor k = i ] \\\).

因而可以将原集合按照元素个数分组做FMT,然后再\(n^2\)次结合,并做IFMT,最终将结果累计,复杂度\(O ( 2^n n^2 )\).

集合占位幂级数

其实就是设\(g_{ i , j } = z^i f_j\),然后做卷积(类似子集卷积).

Example

Example1([AGC034F] RNG and XOR)

\(f_i ( n )\)表示操作\(n\)次后第一次变成\(i\)的概率,\(g_i ( n )\)表示操作\(n\)次后变成\(i\)的概率.\(F , G\)分别是其生成函数.

注意到\(G_i = F_i G_0 , F_i = \frac{ G_i }{ G_0 }\),而\(F_i ' ( 1 )\)就是期望.接下来的问题在于如何求\(G\).

接下来涉及到的东西就很本质了,我们一开始先把\(a_i \rightarrow \frac{ a_i }{ \sum a }\),然后做\(A = FWT ( a )\),注意这里\(A_0 = \sum a = 1\),FWT自身有很好的性质:\(a = \frac{ 1 }{ 2^N } FWT ( A )\).我们做\(n\)次操作后得到的概率数组也就是\(\frac{ 1 }{ 2^N } FWT ( A^n )\).展开FWT的式子,自然有:

\[ \begin{aligned} g_i ( n ) & = \sum_{ j = 0 }^{ 2^N - 1 } ( - 1 )^{ | i \land j | } A_j^n x^n \\ G_i & = \sum_{ j = 0 }^{ 2^N - 1 } ( - 1 )^{ | i \land j | } \frac{ 1 }{ 1 - A_j x } \\ F_i & = \frac{ G_i }{ G_0 } \\ F_i ' & = \frac{ G_i ' G_0 - G_0 ' G_i }{ G_0^2 } \\ & = \frac{ ( \sum_{ j = 0 }^{ 2^N - 1 } ( - 1 )^{ | i \land j | } \frac{ A_j }{ ( 1 - A_j x )^2 } ) ( \sum_{ j = 0 }^{ 2^N - 1 } \frac{ 1 }{ 1 - A_j x } ) - ( \sum_{ j = 0 }^{ 2^N - 1 } \frac{ A_j }{ ( 1 - A_j x )^2 } ) ( \sum_{ j = 0 }^{ 2^N - 1 } ( - 1 )^{ | i \land j | } \frac{ 1 }{ 1 - A_j x } ) }{ ( \sum_{ j = 0 }^{ 2^N - 1 } \frac{ 1 }{ 1 - A_j x } )^2 } \end{aligned} \]

(我草这个式子太顶级了)

但是我们冷静一下,这个题与普通生成函数不同的地方在于,我们要求\(F '_i ( 1 )\),因此我们直接把\(x = 1\)带入算一算就好.不过由于\(A_0 = 1\),我们必须要解决分母为\(0\)的情况,解决的方法是分母乘上\(( 1 - x )\),这样就消掉了\(j = 0\)的项,同时分子由于是减法可以抵消一下.

然后大概做做吧,感觉太顶级了.

Example2([QOJ5089]环覆盖)

合法显然当且仅当每个点度数为偶数,考虑直接拿一个二进制数将每个点度数奇偶性压起来,如果选中一条边\(u \leftrightarrow v\)就异或上\(( 2^u + 2^v )\).最后要求这个二进制数是\(0\).我们用一个二元组\(( a , F )\)表示在集合幂级数上异或上\(a\),在多项式上乘上\(F\).显然一条边是\(( 0 , 1 ) + ( 2^u + 2^v , x )\).注意到这是可以定义乘法运算和标量乘法运算的,也就能做FWT,而且在做FWT的时候要么乘上\(1 + x\)要么乘上\(1 - x\),做完FWT得到的每一个\(FWT_i\)一定形如\(( 1 + x )^k ( 1 - x )^{ m - k }\),做IFWT的时候直接求\(\frac{ 1 }{ 2^N } \sum ( 1 + x )^k ( 1 - x )^{ m - k }\)即可.

仔细想想这个过程:有一句名言是只要看到生成函数就一定存在分配律,这里也是一样的,由于存在一种选择:选不选这条边,因此这里也就有了两种情况:\(( 0 , 1 )\)\(( 2^u + 2^v , x )\),分开两种情况就实现了FWT.

问题在于对于每个\(i\)\(k\),也就是对于每个\(i\)求有多少条边满足\(| i \land ( 2^u + 2^v ) | = 1\),也就是求有多少条边一段链接在了\(i\)的内部,另一端连接在了外部,这个补集转化一下,做高维前缀和.

Example3(CF1034E Little C Loves 3 III)

仍然是子集卷积,转化为\(c_i = \sum_{ j } \sum_{ k } [ | j | + | k | = | i | , j \lor k = i ] a_j b_k \\\).然后我们将\(a_j\)乘上\(4^j\),将\(b_k\)乘上\(4^k\),最后把\(c_i\)除去\(4^i\)\(4\)取膜就行.

还有个用到FWT的本质的矩阵做法,大概是手推矩阵然后再手推求逆.

Example4(CF1336E2 Chiori and Doll Picking)

先考虑easy version.首先求出线性基,如果线性基的大小\(k\)比较小,我们可以直接\(2^k\)枚举一下.而如果线性基较大,我们先消成最简线性基,然后主元位置有多少个\(1\)取决于选了多少个元素,其他位置共有\(m - k\)个,可以直接状压进状态.这样复杂度就是\(O ( \min \{ 2^k , m^2 2^{ m - k } \} )\).

那么我们怎么优化呢?首先\(k\)较大的时候有点难做,我们看看能不能优化到\(2^{ m - k }\).

考虑设\(f_i^c = [ | i | = c ]\),将线性基能做出的线性空间设为\(A\),\(A_S = 1\)当且仅当线性基能异或出\(S\)(最后再把那些废元素贡献到答案里).那么\(popcount = c\)的答案就是\(IFWT ( FWT ( F ) FWT ( A ) )_0\).考虑\(IFWT_0 = \frac{ 1 }{ 2^m } \sum_{ i = 0 }^{ 2^m - 1 } FWT ( F )_i FWT ( A )_i\),问题在于这个东西好像也不好做.

然后接下来开始一波顶级操作(下面的操作全部基于行向量+行操作):

引理1:\(FWT ( A )\)要么是\(2^k\),要么是\(0\).

考虑:

\[ A * A = A \times 2^k \]

这句是为啥呢?因为对于右边的每一个数字\(x\)和左边的一个数字\(y\),如果它们都在线性基中,一定存在一个数字\(z\)满足\(y \oplus z = x\),不然就是\(0\).

于是我们有:

\[ \begin{aligned} FWT ( A )_i \cdot FWT ( A )_i & = FWT ( A )_i \times 2^k \\ FWT ( A )_i & = 0 \lor 2^k \end{aligned} \]

引理2:\(FWT ( A )_i = 2^k \Leftrightarrow \forall x , A_x \ne 0 , | i \land x | \equiv 0 \pmod{ 2 }\).

直接展开上面的式子,用\(\sum_{ S \subseteq T } ( - 1 )^{ | S | } = [ T = \emptyset ]\).

引理3:\(FWT ( A )\)中值为\(2^k\)的位置构成一个线性基.

只需要证明封闭性就好,注意到如果\(i\)满足条件,\(j\)满足条件,一开始做FWT时我们已经注意到:\(( i \oplus j ) \land x = ( i \land x ) \oplus ( j \land x )\).于是这个引理也显然成立.

引理4:\(FWT ( A )\)中值为\(2^k\)的位置构成的线性基的大小是\(m - k\).

设这些位置构成的空间是\(B\),\(B_S = 1\)当且仅当\(S\)在这个空间中.我们有:

\[ \begin{aligned} FWT ( A ) & = B \times 2^k \\ A & = IFWT ( B ) \times 2^k \end{aligned} \]

注意到\(a_0 = 1\),也就是\(\frac{ 2^k }{ 2^m } \sum b = 1 , \sum b = 2^{ m - k }\),这就证明了引理.

引理5:将\(A\)的线性基对应的矩阵从前往后消成最简,\(B\)的线性基对应的矩阵从后往前消成最简,上\(A\)\(B\)拼成一个\(m \times m\)的矩阵,那么这个矩阵关于主对角线对称.

首先根据\(rank ( A ) + rank ( B ) = k + m - k = m\)可以知道主对角线一定全是\(1\),然后我们任取\(A\)中的一个基\(x\)\(B\)中的一个基\(y\),应该有\(| x \land y | \equiv 0 \pmod{ 2 }\).不难发现此时必定对称(画个图,不对称的话考虑主元对他俩的贡献就不是偶数了).

通过这个引理可以由\(A\)得知\(B\)长什么样.

引理6:\(FWT ( F^c )_i\)只和\(| i |\)有关.

因为\(F^c_i\)只和\(| i |\)有关,这里考虑一下对称性就可以.因此设\(w_{ d }^c = FWT ( F^c )_i , | i | = d\).

然后注意到\(w_d^c = \sum_{ i = 0 }^{ 2^m - 1 } ( - 1 )^{ | i \land ( 2^d - 1 ) | } [ | i | = c ]\).组合意义展开一下:

\[ w_d^c = \sum_{ j = 0 }^{ d } ( - 1 )^{ j } \binom{ d }{ j } \binom{ m - d }{ c - j } \]

接下来怎么做呢?令\(g_d = \sum_{ i = 0 }^{ 2^m - 1 } [ A_i = 1 ] [ | i | = d ]\),这里可以\(O ( 2^{ m - k } )\),然后乘起来就行了.

太顶级了吧.

Example5(CF 1326F2)

首先发现”如果没有边那么是\(0\)“这个限制太强了,如果我们能改为”如果是\(0\),那么可有边可无边”的话,整个序列就会被\(1\)的段分成若干两两无关的链.显然这是一步或卷积,这样我们就只需要求后者.如果设\(g_{ len , S }\)表示长度为\(len\),一段长度为\(len - 1\)的连续的\(1\)对应的集合是\(S\)的方案数,不难发现我们最后只需要做一个类似子集卷积的东西就行(前面的每个段会自动在后面放个\(0\)).

但是还没完,题目让我们求每一个,我们不难发现我们这样划分之后答案只取决于链的长度的可重集合,而本质不同的集合的数量很少,直接枚举就行.

Example6(qoj5019)

首先可以类似数位dp设计一个\(dp_{ i , S }\)表示目前dp到了第\(i\)位,然后前面的\(limit\)\(S\).接下来分类讨论当前的最大值限制是\(1\)还是\(0\).

这个题知道题解其实没什么难的,但是这个题告诉了我们:FWT作为一种线性变换,它是可以和其它线性变换一起做的,也就是说你是可以将其中的若干位做FWT,剩下若干位做其它的东西的.

生成函数

普通生成函数(OGF)

概念

我们定义一个幂级数形如\(A ( z ) = \sum_{ k \geq 0 } a_k z^k\),并使\([ z^n ] A ( z ) = a_n\).则称\(A ( z )\)\(\langle a_0 , a_1 , . . . \rangle\)的生成函数.

运算

  1. \(\alpha A ( z ) + \beta B ( z ) = \sum_{ n \geq 0 } ( \alpha f_n + \beta g_n ) z^n\).

  2. \(z^m A ( z ) = \sum_{ n \geq 0 } g_{ n } z^{ n + m } = \sum_{ n \geq m } g_{ n - m } z^n\).

  3. \(A ( cz ) = \sum_{ n \geq 0 } c^n f_n z^n\).

  4. \(A ' ( z ) = \sum_{ n \geq 1 } ig_i z^{ i - 1 }\).

  5. \(\int A ( z ) dz = \sum_{ n \geq 0 } \cfrac{ 1 }{ n + 1 } g_n z^{ n + 1 }\).

  6. \(A ( z ) B ( z ) = \sum_{ n \geq 0 } ( \sum_{ k = 0 }^n f_k g_{ n - k } ) z^n\).

  7. \(\cfrac{ 1 }{ 1 - z } A ( z ) = \sum_{ n \geq 0 } ( \sum_{ k = 0 }^n g_k ) z^n\).

常见序列生成函数

  1. \(\cfrac{ 1 }{ 1 - z } = \sum_{ k \geq 0 } z^k \\\),\(\cfrac{ 1 }{ 1 - cz } = \sum_{ k \geq 0 } c^k z^k \\\).

证明显然.

  1. \(( 1 + z )^r = \sum_{ k \geq 0 } \binom{ r }{ k } z^k \\\),\(( 1 - z )^r = \sum_{ k \geq 0 } ( - 1 )^k \binom{ r }{ k } z^k \\\).

证明根据二项式定理.

  1. \(\cfrac{ 1 }{ 1 - z^m } = \sum_{ n \geq 0 } [ n | m ] z^n \\\).

证明显然.

  1. \(\cfrac{ 1 }{ ( 1 - z )^{ n + 1 } } = \sum_{ k \geq 0 } \binom{ n + k }{ n } z^k , n \in \mathbb{ N } \\\),\(\cfrac{ z^n }{ ( 1 - z )^{ n + 1 } } = \sum_{ k \geq 0 } \binom{ k }{ n } z^k , n \in \mathbb{ N } \\\)

直接使用二项式定理展开\(( 1 - z )^{ - n - 1 }\),可以得到:

\[ ( 1 - z )^{ - n - 1 } = \sum_{ k \geq 0 } ( - 1 )^k \binom{ - n - 1 }{ k } z^k \]

反转上指标并使用对称恒等式得到上式.此外上式还有两个特殊形式:

\[ \begin{aligned} \cfrac{ 1 }{ ( 1 - z )^2 } & = \sum_{ n \geq 0 } ( n + 1 ) z^n \\ \cfrac{ z }{ ( 1 - z )^2 } & = \sum_{ n \geq 0 } nz^n \end{aligned} \]

根据\(( 1 )\)求导即可得到此式.

  1. \(e^z = \sum_{ k \geq 0 } \cfrac{ z^k }{ k ! } \\\).

  2. \(\ln ( \cfrac{ 1 }{ 1 - z } ) = \sum_{ n \geq 1 } \cfrac{ 1 }{ n } z^n\).

  3. \(\ln ( 1 + z ) = \sum_{ k \geq 0 } ( - 1 )^k \cfrac{ z^{ k + 1 } }{ k + 1 } \\\).

可以使用积分或泰勒展开证明.

  1. \(\frac{ 1 - \sqrt{ 1 - 4 x } }{ 2 x } = \sum_{ k \geq 0 } \frac{ \binom{ 2 k }{ k } }{ k + 1 } x^k\).

也即卡特兰数\(C_k\)的生成函数,证明考虑:

\[ xC^2 + 1 = C \]

然后得到两个根,带入\(x = 0\)舍掉一个.

指数生成函数(EGF)

https://zhuanlan.zhihu.com/p/53079223

序列\(\{ a \}\)的指数生成函数定义为形式幂级数\(\hat F ( x ) = \sum a_n \frac{ x^n }{ n ! }\).注意\([ x^n ] \hat F ( x ) = a_n\).

基本运算

我们有:

\[ \begin{aligned} \hat F ( x ) \hat G ( x ) & = \sum_{ j \geq 0 } a_j \frac{ x^j }{ j ! } \sum_{ k \geq 0 } b_k \frac{ x^k }{ k ! } \\ & = \sum_{ k \geq 0 } x^k \sum_{ j = 0 }^k a_j b_{ k - j } \frac{ k ! }{ j ! ( k - j ) ! } \frac{ 1 }{ k ! } \\ & = \sum_{ k \geq 0 } \frac{ x^k }{ k ! } \sum_{ j = 0 }^k a_j b_{ k - j } \binom{ k }{ j } \end{aligned} \]

\(\langle \sum_{ i = 0 }^n \binom{ n }{ i } a_i b_{ n - i } \rangle\)的EFG.

注意到有一个特例是\(x \hat F ( x )\)就是\(\langle \binom{ n }{ n - 1 } a_i \rangle\)的EGF.

封闭式

  1. \(e^x = \sum_{ k \geq 0 } \frac{ x^k }{ k ! }\)

直接泰勒展开就可以得到

  1. \(e^{ px } = \sum_{ k \geq 0 } p^k \frac{ x^k }{ k ! }\)

换元后可以得到.一个经典特例是\(e^{ - x } = \sum_{ k \geq 0 } ( - 1 )^k \frac{ x^k }{ k ! }\).

  1. \(\frac{ e^x + e^{ - x } }{ 2 } = \sum_{ k \geq 0 } [ 2 | k ] \frac{ x^k }{ k ! }\).

显然.

  1. \(( 1 + x )^n = \sum_{ k \geq 0 } n^{ \underline{ k } } \frac{ x^k }{ k ! }\).

做二项式定理就显然了.

  1. \(\ln ( 1 + x ) = \sum_{ k \geq 1 } ( - 1 )^{ k - 1 } ( k - 1 ) ! \frac{ x^k }{ k ! }\).

  2. \(\ln ( 1 - x ) = \sum_{ k \geq 1 } ( k - 1 ) ! \frac{ x^k }{ k ! }\).

都可以通过泰勒展开证明.

EXP的组合意义

我们设\(F_k ( n )\)\(n\)个有标号元素划分成\(k\)个非空无序集合的情况,\(f_i\)\(i\)个元素组成一个集合的时候,其上特定组合结构的数量(就是一个一个只和\(| S |\)有关的定义在集合上的函数),有:

\[ F_k ( n ) = \frac{ n ! }{ k ! } \sum_{ \sum_{ i = 1 }^k a_i = n } \prod_{ j = 1 }^k \frac{ f_{ a_j } }{ a_j ! } \]

\(\hat{ F } ( x ) = \sum_{ n \geq 0 } f_n \frac{ x^n }{ n ! }\),再设:

\[ \begin{aligned} \hat G_k ( x ) & = \sum_{ n \geq 0 } F_k ( n ) \frac{ x^n }{ n ! } \\ & = \sum_{ n \geq 0 } x^n \frac{ 1 }{ k ! } \sum_{ \sum_{ i = 1 }^k a_i = n } \prod_{ j = 1 }^k \frac{ f_{ a_j } }{ a_j ! } \\ & = \sum_{ n \geq 0 } \frac{ 1 }{ k ! } \sum_{ \sum_{ i = 1 }^k a_i = n } \prod_{ j = 1 }^k \frac{ f_{ a_j } x^{ a_j } }{ a_j ! } \\ & = \frac{ 1 }{ k ! } \hat F^k ( x ) \end{aligned} \]

\[ \sum_{ k \geq 0 } \hat G_k ( x ) = \exp \hat F ( x ) \]

或者直接递推:

$$ \[\begin{aligned} F_k ( x ) & = \sum_{ i = 1 }^{ n - k + 1 } \binom{ n }{ i } F_{ k - 1 } ( n - i ) f_i \frac{ 1 }{ k } \\ \end{aligned}\]

$$

\[ \begin{aligned} \hat G_k ( x ) & = \sum_{ n \geq 0 } \frac{ x^n }{ n ! } F_k ( n ) \\ & = \sum_{ n \geq 0 } \frac{ x^n }{ n ! } \sum_{ i = 1 }^{ n - k + 1 } \binom{ n }{ i } F_{ k - 1 } ( n - i ) f_i \frac{ 1 }{ k } \\ & = \frac{ 1 }{ k } \sum_{ n \geq 0 } \frac{ x^n }{ n ! } \sum_{ i = 1 }^{ n - k + 1 } \binom{ n }{ i } F_{ k - 1 } ( n - i ) f_i \\ & = \frac{ 1 }{ k } \hat G_{ k - 1 } ( x ) \hat F ( x ) \\ & = \frac{ 1 }{ k ! } \hat F^k ( x ) \end{aligned} \]

简而言之,\([ x^n ] \hat F ( x )\)是将\(n\)个有标号的元素放到同一个无序集合的方案数,而\([ x^n ] \exp \hat F ( x )\)是将\(n\)个有标号的元素分成若干个无编号的非空无序集合的方案数.

Example

Example1(POJ3734)

对于红黄色砖块,其选取方案为\(\{ 1 , 0 , 1 , 0 , \cdots \}\),对应的EGF是\(\frac{ e^x + e^{ - x } }{ 2 }\).

对于蓝绿色砖块,选取方案是\(e^x\).

乘起来有:

\[ \begin{aligned} \hat F ( x ) & = ( \frac{ e^x + e^{ - x } }{ 2 } )^2 e^{ 2 x } \\ & = \frac{ ( e^{ 2 x } + 2 + e^{ - 2 x } ) e^{ 2 x } }{ 4 } \\ & = \frac{ e^{ 4 x } + 2 e^{ 2 x } + 1 }{ 4 } \\ & = \frac{ 1 }{ 4 } + \sum_{ k \geq 0 } \frac{ 4^i + 2^{ i + 1 } }{ 4 } \frac{ x^i }{ i ! } \end{aligned} \]

于是有\([ x^n ] \hat F ( x ) = 4^{ n - 1 } + 2^{ n - 1 }\).

Example2(圆排列)

长度为\(n\)的排列数的指数生成函数是\(\hat P ( x ) = \sum_{ n \geq 0 } \frac{ n ! x^n }{ n ! } = \frac{ 1 }{ 1 - x }\).

长度为\(n\)的圆排列的指数生成函数是\(\hat Q ( x ) = \sum_{ n \geq 0 } \frac{ ( n - 1 ) ! x^n }{ n ! } = \frac{ x^n }{ n } = - \ln ( 1 - x ) = \ln \frac{ 1 }{ 1 - x }\).

于是有\(\exp \hat Q ( x ) = \hat P ( x )\).

这个怎么理解呢?考虑一个排列可以分成若干个置换环,而一个集合能形成的置换环数量显然就是圆排列.

Example3(错排数)

从置换环的角度考虑,错排是指置换环中不存在自环的排列,也就是说不存在长度为\(1\)的置换环,其EGF显然是\(\sum_{ n \geq 2 } \frac{ x^n }{ n } = - \ln ( 1 - x ) - x\),错排数的EGF对其取\(\exp\)即可.

Example4(点带编号无向连通图计数)

考虑如果\(n\)个点带编号的无向连通图的EGF是\(\hat F ( x )\),那么\(n\)个点带标号无向图的EGF就是\(\exp \hat F ( x )\),后者直接计数,前者对后者做一次\(\ln\)就好.

Example5(不动点计数)

求有多少个映射\(f : \{ 1 , 2 , \cdots , n \} \mapsto \{ 1 , 2 , \cdots , n \}\)满足\(f \circ f \circ \cdots \circ f\)(共\(k\)\(f\))\(= f \circ f \circ \cdots \circ f\)(共\(k - 1\)\(f\)).

考虑将\(i \rightarrow f_i\),这等价于对深度不超过\(k\)的基环树(环的长度为\(1\))计数,等价于对深度不超过\(k\)的有根树计数.注意到删去根节点后等价于对深度不超过\(k - 1\)的有根树计数,因此\(\hat F_k ( x ) = x \exp \hat F_{ k - 1 } ( x )\).

Example6([CF891E]Lust)

假设\(k\)次操作后\(a_i\)减少了\(b_i\),实际上要求的就是\(\prod_{ i = 1 }^n a_i - \prod_{ i = 1 }^n ( a_i - b_i )\).

考虑对所有情况下的\(\prod_{ i = 1 }^n ( a_i - b_i )\)求和,注意到\(k\)次操作,使得\(i\)出现\(b_i\)次的方案数是\(\frac{ k ! }{ \prod_{ i = 1 }^n b_i ! }\).直接设\(a_j\)的EGF是

\[ \begin{aligned} \hat F_{ j } ( x ) & = \sum_{ i \geq 0 } ( a_j - i ) \frac{ x^i }{ i ! } \\ & = \sum_{ i \geq 0 } a_j \frac{ x^i }{ i ! } - \sum_{ i \geq 1 } \frac{ x^i }{ ( i - 1 ) ! } \\ & = a_j e^x - xe^x = ( a_j - x ) e^x \end{aligned} \]

答案就是\([ x^k ] \prod_{ j = 1 }^n \hat F_j ( x )\).

Example7

狄利克雷生成函数(DGF)

对于序列\(f_n\),定义其DGF为\(\tilde{ F } ( x ) = \sum_{ i \geq 1 } \frac{ f_i }{ i^x }\).注意到若\(f\)是积性函数,那么\(\tilde{ F } ( x ) = \prod_{ p \in \mathrm{ prime } } \sum_{ i \geq 0 } \frac{ f_{ p^i } }{ p^{ ix } } \\\).

基本运算

对于两个序列\(f , g\),其DGF之积对应的是两者的狄利克雷卷积序列的DGF:

\[ \begin{aligned} \tilde{ F } ( x ) \tilde{ G } ( x ) & = \sum_{ i } \sum_{ j } \frac{ f ( i ) g ( j ) }{ ( ij )^x } \\ & = \sum_{ i } \frac{ 1 }{ i^x } \sum_{ d | i } f ( d ) g ( \frac{ i }{ d } ) \end{aligned} \]

封闭式

  1. \(\epsilon ( x ) = [ x = 1 ]\).

显然为\(\tilde{ E } ( x ) = 1\).

  1. \(I ( x ) = 1\).

其封闭式是黎曼函数\(\zeta ( x )\),事实上,我们有:

\[ \begin{aligned} \zeta ( x ) & = \prod_{ i \geq 1 } \frac{ 1 }{ i^x } \\ & = \prod_{ p \in \mathrm{ prime } } \sum_{ i \geq 0 } \frac{ 1 }{ p^{ ix } } \\ & = \prod_{ p \in \mathrm{ prime } } \frac{ 1 }{ 1 - p^{ - x } } \end{aligned} \]

  1. \(\mu ( n )\).

其DGF为\(\tilde{ M } ( x ) = \prod_{ p \in \mathrm{ prime } } ( 1 - p^{ - x } )\).注意到\(\zeta ( x ) \tilde{ M } ( x ) = 1 , \tilde{ M } ( x ) = \frac{ 1 }{ \zeta ( x ) }\).

  1. \(id ( n ) = n\).

\(\tilde{ ID } ( n ) = \prod_{ i \geq 1 } \frac{ i }{ i^x } = \prod_{ i \geq 1 } \frac{ 1 }{ i^{ x - 1 } } = \zeta ( x - 1 )\).

  1. \(I_k ( n ) = n^k\).

\[ \tilde{ I_k } ( x ) = \prod_{ i \geq 1 } \frac{ 1 }{ i^{ x - k } } = \zeta ( x - k ) \]

  1. \(\varphi ( n )\).

注意到:

\[ \begin{aligned} \tilde{ \Phi } ( x ) & = \prod_{ p \in \mathrm{ prime } } ( 1 + \frac{ p - 1 }{ p^x } + \frac{ p ( p - 1 ) }{ p^{ 2 x } } + \cdots ) \\ & = \prod_{ p \in \mathrm{ prime } } \frac{ 1 - p^{ - x } }{ 1 - p^{ 1 - x } } \\ & = \tilde{ \Phi } ( x ) = \frac{ \zeta ( x - 1 ) }{ \zeta ( x ) } \end{aligned} \]

也注意到\(\tilde{ \Phi } ( x ) I ( x ) = \zeta ( x - 1 ) = \tilde{ ID } ( x )\).

  1. \(\sigma_k ( n ) = \sum_{ d | n } d^k\).

注意到\(\sigma_k ( n ) = I_k ( n ) * I_0 ( n )\),也就是说\(\tilde{ S } ( x ) = \zeta ( x - k ) \zeta ( x )\).

  1. \(u ( n ) = | \mu ( n ) |\).

\(\tilde{ u } ( n ) = \frac{ \zeta ( n ) }{ \zeta ( 2 n ) }\).

Example

Example1(luoguP3768)

考虑对于\(f ( n ) = n^2 \varphi ( n )\)构造积性函数\(g ( n ) , h ( n )\)使得\(f * g = h\).

注意到:

\[ \begin{aligned} \tilde{ F } ( x ) & = \prod_{ p \in \mathrm{ prime } } ( 1 + \sum_{ k \geq 1 } \frac{ p^{ 3 k - 1 } ( p - 1 ) }{ p^{ kx } } ) \\ & = \prod_{ p \in \mathrm{ prime } } \frac{ 1 - p^{ 2 - x } }{ 1 - p^{ 3 - x } } = \frac{ \zeta ( x - 3 ) }{ \zeta ( x - 2 ) } \end{aligned} \]

也就是\(f * I_2 = I_3\).

阶乘的扩展定义

对于复数的阶乘,我们通常定义:

\[ \cfrac{ 1 }{ z ! } = \lim_{ n \rightarrow + \infin } \binom{ n + z }{ z } n^{ - z } \]

同时我们定义\(\Gamma ( z + 1 ) = z !\),有:\(( - z ) ! \Gamma ( z ) = \cfrac{ \pi }{ \sin ( \pi z ) }\).

这样我们还可以定义广义阶乘幂:

\[ \begin{aligned} z^{ \underline{ w } } & = \cfrac{ z ! }{ ( z - w ) ! } \\ z^{ \overline{ w } } & = \cfrac{ \Gamma ( z + w ) }{ \Gamma ( z ) } \end{aligned} \]

通过以上我们还可以有二项式系数的定义:

\[ \binom{ z }{ w } = \lim_{ \zeta \rightarrow z , \omega \rightarrow w } \cfrac{ \zeta ! }{ \omega ! ( \zeta - \omega ) ! } \]

超几何级数

超几何函数

我们定义超几何函数\(F ( a_1 , . . . , a_m ; b_1 , . . . b_n ; z ) = F \left ( \begin{array}{ r | } a_1 , . . . , a_m \\ b_1 , . . . , b_n\end{array} z \right ) = \sum_{ k \geq 0 } \cfrac{ z^k \prod_{ i = 1 }^m a_i^{ \overline{ k } } }{ k ! \prod_{ i = 1 }^n b_i^{ \overline{ k } } }\).

许多生成函数都可以写成超几何函数的形式.

值得一提的是,如果我们直接定义类似\(\cfrac{ 0 }{ 0 } = 1\)之类的式子,可以发现当\(z = 0\)时任意超几何函数总是\(= 1\).

值得一提的是,我们通常直接忽略超几何函数中的任何特殊情况,例如分母为\(0\)或者哪里出现了正无穷.如同生成函数中我们不关心式子带入一个数后是否收敛而只关心是否两边存在一种对应的转化.如果你想去探究超几何函数中的各种情况,那请去翻那本巨大的、黑糊糊的、作者默认你精通高等数学的、你在第五章看到的恒等式作者在第七章才给出证明的《具体数学》,而不是看我这个弱智写的笔记.笔者看这一段的时候已经被作者的”严谨”态度整疯了.该证明的一拖再拖不该证明的可以一句话带过的逼逼逼逼.仿佛这本书就是写给那些已经会了所有东西只是来使自己已经学会的东西更加体系化的以及拿来查阅各种恒等式的工具书.

特殊的超几何函数

合流超几何函数

我们通常把形如\(M ( a ; b ; z ) = F \left ( \begin{array}{ r | } a \\ b\end{array} z \right ) = \sum_{ k \geq 0 } \cfrac{ z^k a^{ \overline{ k } } }{ b^{ \overline{ k } } k ! }\)的函数称为合流超几何函数.

不难发现我们有:

\[ F \left ( \begin{array} { r | } 1 \\ 1 \end{array} z \right ) = e^z \]

也即常见生成函数中的\(( 6 )\).

高斯超几何函数

我们把形如\(F \left ( \begin{array}{ r | } a , b \\ c\end{array} z \right ) = \sum_{ k \geq 0 } \cfrac{ z^k a^{ \overline{ k } } b^{ \overline{ k } } }{ c^{ \overline{ k } } k ! }\)的函数称为高斯超几何函数.

下面是几种常见的高斯超几何函数形式:

  1. \(F \left ( \begin{array}{ r | } 1 , 1 \\ 1\end{array} z \right ) = \cfrac{ 1 }{ 1 - z }\).

即常见生成函数\(( 1 )\).

  1. \(F \left ( \begin{array}{ r | } - a , 1 \\ 1\end{array} - z \right ) = ( 1 + z )^a\).

即常见生成函数\(( 2 )\).

  1. \(F \left ( \begin{array}{ r | } a , 1 \\ 1\end{array} z \right ) = \cfrac{ 1 }{ ( 1 - z )^a }\).

即常见生成函数\(( 4 )\).

  1. \(F \left ( \begin{array}{ r | } 1 , 1 \\ 2\end{array} - z \right ) = \cfrac{ \ln ( 1 + z ) }{ z }\).

即常见生成函数\(( 7 )\).

超几何级数的应用

我们先考虑改写超几何级数的形式:

\(F \left ( \begin{array}{ r | } a_1 , . . . , a_m \\ b_1 , . . . , b_n\end{array} z \right ) = \sum_{ k \geq 0 } t_k , t_k = \cfrac{ z^k \prod_{ i = 1 }^m a_i^{ \overline{ k } } }{ k ! \prod_{ i = 1 }^n b_i^{ \overline{ k } } }\).

不难发现\(t_0 = 1\),而:

\[ \begin{aligned} \cfrac{ t_{ k + 1 } }{ t_k } & = \cfrac{ z^{ k + 1 } }{ z^k } \cfrac{ k ! }{ ( k + 1 ) ! } \cfrac{ \prod_{ i = 1 }^m a_i^{ \overline{ k + 1 } } }{ \prod_{ i = 1 }^m a_i^{ \overline{ k } } } \cfrac{ \prod_{ i = 1 }^n b_i^{ \overline{ k } } }{ \prod_{ i = 1 }^n b_i^{ \overline{ k + 1 } } } \\ & = \cfrac{ \prod_{ i = 1 }^m ( k + a_i ) }{ \prod_{ i = 1 }^n ( k + b_i ) } \cfrac{ z }{ k + 1 } \end{aligned} \]

换句话说,\(\cfrac{ t_{ k + 1 } }{ t_k }\)是关于\(k\)的一个有理函数.而根据代数基本定理,任意\(k\)的有理函数在\(\mathbb{ C }\)内都可以分解为以上的形式(如果缺少\(k + 1\)项则需要上下同时乘以\(k + 1\)以补上).

换句话说,对于一个无穷级数\(\sum_{ k \geq 0 } t_k\),我们先将\(\cfrac{ t_{ k + 1 } }{ t_k }\)表示回超几何函数,设为\(F\).

那么有:\(\sum_{ k \geq 0 } t_k = t_0 F\).

好,接下来请把脑子扔了,不要纠结某一个公式按理来说只能作用于正整数而在这里直接将它套在了复数域上.你只需要知道数学家非常厉害通过扩展一些东西的定义(大部分是阶乘和\(\Gamma\)函数的定义)来使这些公式全部成立.But who cares,只要我们能用就行了.我又不是数竞人,这些麻烦的要死我直观上根本无法接受的定义交给数竞老哥证明得了.反正信竞更多依赖离散数学,大不了我们直接默认所有的数都是自然数.

Example

求证:\(\sum_{ k \leq n } \binom{ r + k }{ k } = \binom{ r + n + 1 }{ n } \Leftrightarrow F \left ( \begin{array}{ r | } 1 , - n \\ - n - r\end{array} 1 \right ) = \cfrac{ r + n + 1 }{ r + 1 } , n \in \mathbb{ N } \\\).

首先考虑:

\[ \sum_{ k \leq n } \binom{ r + k }{ k } = \sum_{ k \geq 0 } \binom{ r + n - k }{ n - k } \]

有了这个无穷级数,我们可以直接将二项式系数用阶乘形式展开,于是得到:

\[ \binom{ r + n }{ n } F \left ( \begin{array} { r | } 1 , - n \\ - n - r \end{array} 1 \right ) = \binom{ r + n + 1 }{ n } \]

两边同时除以\(\binom{ r + n }{ n }\)得到上式.

二项式系数与超几何函数

通过范德蒙德卷积,不难验证:

\[ F \left ( \begin{array} { r | } a , b \\ c \end{array} 1 \right ) = \cfrac{ \Gamma ( c - a - b ) \Gamma ( c ) }{ \Gamma ( c - a ) \Gamma ( c - b ) } , - b \in \mathbb{ N } \]

这个公式的一个特例是:

$$ \[\begin{aligned} F \left ( \begin{array} { r | } a , - n \\ c \end{array} 1 \right ) & = \cfrac{ ( c - a )^{ \overline{ n } } }{ c^{ \overline{ n } } } = \cfrac{ ( a - c )^{ \underline{ n } } }{ ( - c )^{ \underline{ n } } } , n \in \mathbb{ N } \\ \sum_{ k \geq 0 } \cfrac{ a^{ \overline{ k } } ( - n )^{ \overline{ k } } }{ c^{ \overline{ k } } k ! } & = \cfrac{ ( c - a )^{ \overline{ n } } }{ c^{ \overline{ n } } } = \cfrac{ ( a - c )^{ \underline{ n } } }{ ( - c )^{ \underline{ n } } } , n \in \mathbb{ N } \\ \end{aligned}\]

$$

这个公式几乎囊括了所有的基本二项式求和公式:上指标求和,平行求和,范德蒙德卷积……几乎只要是我们推出的由两个及以下项的乘积求和的二项式系数相关的式子都可以使用这个式子.

那么如果我们要三项相乘或更多,我们有Saalschütz恒等式:

$$ \[\begin{aligned} F \left ( \begin{array} { r | } a , b , - n \\ c , a + b - n - c + 1 \end{array} 1 \right ) & = \cfrac{ ( c - a )^{ \overline{ n } } ( c - b )^{ \overline{ n } } }{ c^{ \overline{ n } } ( c - a - b )^{ \overline{ n } } } = \cfrac{ ( a - c )^{ \underline{ n } } ( b - c )^{ \underline{ n } } }{ ( - c )^{ \underline{ n } } ( a + b - c )^{ \overline{ n } } } , n \in \mathbb{ N } \\ \end{aligned}\]

$$

事实上,《具体数学》上给出了大量的超几何级数的应用以及各种技巧,但是笔者的智商已经理解不了接下来的内容了.考虑到大部分时候上述两个超几何级数恒等式已经足够解决绝大部分问题,如果考到更加困难的求和技巧,笔者相信别人也不会做,于是笔者决定摆烂.

求微分方程

Example1(luogu4931)

二项式反演:

\[ \begin{aligned} ans_k & = \sum_{ i = k }^n ( - 1 )^{ i - k } \binom{ i }{ k } \binom{ n }{ i } \binom{ n }{ i } i ! ( 2 n - 2 i ) ! 2^i \\ & = \sum_{ i = k }^n ( - 1 )^{ i - k } \frac{ 1 }{ k ! ( i - k ) ! } \frac{ n ! }{ ( n - i ) ! } \frac{ n ! }{ ( n - i ) ! } ( 2 n - 2 i ) ! 2^i \\ & = ( n ! )^2 \frac{ 2^k }{ k ! } \sum_{ i = k }^n ( - 1 )^{ i - k } \frac{ 1 }{ ( i - k ) ! } \binom{ 2 n - 2 i }{ n - i } 2^{ i - k } \\ & = ( n ! )^2 \frac{ 2^k }{ k ! } \sum_{ i = 0 }^{ n } \frac{ ( - 2 )^{ i } }{ i ! } \binom{ 2 n - 2 i }{ n - i } \end{aligned} \]

注意到后者只与\(n - k\)有关,不妨设其为\(f_{ n } = \sum_{ i = 0 }^{ n } \frac{ ( - 2 )^{ i } }{ i ! } \binom{ 2 n - 2 i }{ n - i }\),预处理一下就可以做到\(O ( n^2 + nT )\).

加强版咋做?我们继续看看式子:

\[ \begin{aligned} ans & = ( n ! )^2 \frac{ 2^k }{ k ! } f_{ n - k } \\ f_{ n } & = \sum_{ i = 0 }^{ n } \frac{ ( - 2 )^{ i } }{ i ! } \binom{ 2 n - 2 i }{ n - i } \end{aligned} \]

注意到\(f\)是一个卷积的形式,设其生成函数为\(F_n\),\(g_n = \frac{ ( - 2 )^n }{ n ! } , h_n = \binom{ 2 n }{ n }\),我们自然有\(F = GH\).

考虑\(G\)\(H\)的生成函数形式,先看\(G\),显然用泰勒展开:

\[ G = \sum_{ n \geq 0 } \frac{ ( - 2 x )^n }{ n ! } = e^{ - 2 x } \]

再看\(H\),是卡特兰数的生成函数,有:

\[ H = \frac{ 1 }{ \sqrt{ 1 - 4 x } } \]

这下简单了,答案是:

\[ ( n ! )^2 \frac{ 2^k }{ k ! } [ x^{ n - k } ] \frac{ e^{ - 2 x } }{ \sqrt{ 1 - 4 x } } \]

现在看\(F\),平方一下有:

\[ ( 1 - 4 x ) F^2 = e^{ - 4 x } \]

两边求导:

$$ \[\begin{aligned} - 4 F^2 + ( 1 - 4 x ) 2 F \times F ' & = - 4 e^{ - 4 x } \\ - 4 F^2 + ( 1 - 4 x ) 2 F \times F ' & = - 4 ( 1 - 4 x ) F^2 \\ ( 2 - 8 x ) F ' & = 16 xF \\ \end{aligned}\]

$$

得到了一个线性递推形式,更进一步地:

\[ \begin{aligned} 2 ( i + 1 ) f_{ i + 1 } - 8 if_i & = 16 f_{ i - 1 } \\ if_i & = 4 ( i - 1 ) f_{ i - 1 } + 8 f_{ i - 2 } \end{aligned} \]

技术总结一下:其实就是你想要得到一个递推式,然后注意到这玩意要写成微分方程的形式,所以开始往那边凑.

生成函数的应用

求解递归关系

我们假设已经有了\(R ( z ) = \sum_{ k \geq 0 } g_k z^k\),并且\(R ( z ) = \cfrac{ P ( z ) }{ Q ( z ) }\),其中\(P ( z )\)\(Q ( z )\)都是多项式,我们想要找到一种方式求解\([ z^n ] R ( z )\).

考虑有理函数\(S ( z ) = \sum_{ k = 1 }^m \cfrac{ a_k }{ 1 - \rho_k z } \\\),不难发现\([ z^n ] S ( z ) = \sum_{ k = 1 }^m a_k \rho_k^n \\\).

那么可以证明,只要\(Q ( z ) = 0\)无重根并且无零根,那么就存在一组系数满足\(S ( z ) = R ( z )\).

我们这么定义”反射”运算,若\(Q ( z ) = \sum_{ k = 0 }^m q_k z^k \\\),则其反射多项式为\(Q^R ( z ) = \sum_{ k = 0 }^m q_k z^{ m - k } \\\).

\(Q ( z ) = q_0 \prod_{ k = 1 }^m ( 1 - \rho_k z )\),则显然有\(Q^R ( z ) = q_0 \prod_{ k = 1 }^m ( z - \rho_k ) \\\).

那么显然这里求出来的这组数\(\rho\)就是\(S ( z )\)中的那组\(\rho\).

而我们有\(a_k = \cfrac{ - \rho_k P ( \cfrac{ 1 }{ \rho_k } ) }{ Q ' ( \rho_k ) }\).

Example1

已知\(n ! = \sum_{ k } \binom{ n }{ k } g_{ n - k } , n \in \mathbb{ N } \\\),求\(g_n\).

首先两边同时除以\(n !\)并将组合数用阶乘形式展开,我们有:

\[ 1 = \sum_{ k } \cfrac{ g_{ n - k } }{ k ! ( n - k ) ! } . \]

如果我们令\(D ( z ) = \sum_{ k \geq 0 } \cfrac{ g_{ k } }{ k ! } z^k\),则有:

\[ \begin{aligned} \cfrac{ 1 }{ 1 - z } & = e^z D ( z ) \\ D ( z ) & = \cfrac{ 1 }{ 1 - z } e^{ - z } \\ D ( z ) & = ( \sum_{ k \geq 0 } z^k ) ( \sum_{ k \geq 0 } ( - 1 )^k \cfrac{ z^k }{ k ! } ) \\ [ z^n ] D ( z ) & = \sum_{ k = 0 }^n \cfrac{ ( - 1 )^k }{ k ! } \end{aligned} \]

于是\(g_n = n ! \sum_{ k = 0 }^n \cfrac{ ( - 1 )^k }{ k ! } \\\).

Example2([QOJ5169] 夹娃娃)

首先设\(F_i ( x )\)为第\(i\)家的生成函数,这个是显然可以快速预处理出来的.令\(M = 520\).

问题在于每次询问的时候求出答案呢?

这里有一个套路:我们在一开始就暴力做点值,最后拿拉格朗日插值求答案.中间大概把能预处理的都预处理一下.最后的问题在于:

第一,预处理点值的时候,一共有\(n\)个多项式,最高次数是\(M\),因此一共要插入\(nM\)个值,又要处理每个后缀,复杂度来到\(O ( n^2 M^3 )\).这个问题是好解决的.我们只需要在带入点值的时候做一个后缀继承一类的东西,复杂度就可以来到\(O ( n^2 M^2 )\).

第二,询问的时候需要找到所有对应的点值并暴力乘起来,复杂度来到\(O ( n^2 Mq )\).但\(n\)如此小,我们可以用指数级别的复杂度来优化,我们考虑预处理一下\(2^n\)的答案,复杂度来到\(O ( nM 2^n q )\).但是这个更不太行.那怎么办呢?我们把这个指数级别的东西分块一下.预处理复杂度来到\(O ( \frac{ n }{ B } B 2^B MnM )\),单次询问复杂度来到\(O ( \frac{ n }{ B } Mnq )\).但这个预处理复杂度好像还是有点艰难.不过注意到如果做一个剪枝优化:如果总共的喜欢的店的个数乘以\(k\)要大于\(m\),就直接输出\(0\).预处理的时候块内部也做一个剪枝,然后发现就能过了(牛逼).

第三,拉格朗日插值的时候需要\(O ( ( nM )^2 q )\)的复杂度,不过由于点值可以自己控制,这个复杂度可以轻松降到\(O ( nMq )\).

Example3([十二省联考 2019] 皮配)

首先注意到题目等价于规定一个阵营和一个排序的人数上下界.

我们可以将这四位导师分别记为\(xy , y , x , 1\),这样最后判断幂在一个区间内的\(x\)\(y\)前面的系数就行.

注意到如果没有学校有偏好,将生成函数卷起来后得到的答案就是\(\prod ( x^{ s_i } y^{ s_i } + x^{ s_i } ) + \prod ( y^{ s_i } + 1 ) = ( \prod ( x^{ s_i } + 1 ) ) ( \prod ( y^{ s_i } + 1 ) )\).也就是\(x\)\(y\)是互相独立的,我们可以分开算.

对于那些有偏好的学校,我们暴力算就行.复杂度不会高于\(O ( mk^2 s )\).最后两部分合并一下.

约定

\(K_n\)\(n\)个点的完全图

树的性质

Example1([HDU6035]Colorful Tree)

考虑每种颜色的贡献,一种颜色的贡献显然是删去所有这个颜色的边后,剩下的联通块之间的路径.

Example2([2022qbxt国庆Day1]tree)

首先考虑分开处理每个点,在做每个点的时候假设它的所有子节点全部已经满足条件了,最终我们再通过计算组合数的方式计算即可.

那么最后,我们需要对于每个点进行处理,假设我们已知这个子树的集合是\(S\),那么我们需要用容斥计算如果当前子树集合是\(S\)的子集的情况,不难发现容斥式子:

\[ ans = \sum_{ k = \max \{ f_v | x \rightarrow v \} }^{ f_x } ( - 1 )^{ f_x - k } k \binom{ f_x }{ k } \sum_{ x \rightarrow v } \binom{ k }{ f_v } \]

其实也就是个二项式反演的形式.

这题还需要一些技巧优化,我们首先发现由于\(f_v\)有可能有重复的,我们可以提前把重复的\(f_v\)压缩到一起再用快速幂求,于是后面的部分最多不过\(\sqrt{ n }\)级别.而前面是一个类似于树上启发式合并的东西,于是复杂度\(O ( n \sqrt{ n } \log n )\).

Example3(CF1628E Groceries in Meteor Town)

因为要求路径最大值,所以先建Kruskal重构树.然后问题转化为求一个点和一群白点的LCA是谁.

树上多点LCA有个经典性质:也就相当于其中\(dfn\)序最大的和最小的两个点的LCA.

至于区间覆盖可以用线段树.

Example4(loj3692)

注意到\(D\)很小.

我们考虑处理邻域乘,设\(f_{ x , i }\)表示\(x\)\(i\)级儿子需要乘上的答案.每次修改时,先将\(f_{ x , D }\)\(f_{ x , D - 1 }\)乘上\(W\),然后令\(x = fa_x\),\(D = D - 2\),继续此操作直到\(D\)\(0\).

然后询问的时候直接暴力跳\(D\)层父亲找答案,不难发现这样做是对的.

同样的思路可以脱离点分治处理很多邻域问题.

树的直径

  1. 定义:树中最长的一条简单路径.

  2. 树的直径可能有多个.

  3. 直径的两个端点一定是两个叶子节点.

  4. 如果树有多条直径,树的不同的直径的中点/中边一定是相同的.

  5. 到一个点距离最远的点一定是直径的一个端点.

  6. 对于两棵树,如果第一棵树直径两端点为\(( u , v )\),第二棵树直径两端点为\(( x , y )\),用一条边将两棵树连接,那么新树的直径一定是\(u , v , x , y\)中的两个点.

上述的证明大都是考虑反证法:如果不成立,则一定存在一条更长的直径.

Example1([SDOI2013]直径)

有一个做法是:考虑找到直径的中点/中边,找到它到两边的最远距离的点,显然两边的点分别的以中点/中边的两个端点为根的LCA中间的部分就是一定会被包含的边.

树的重心

  1. 定义:树的重心是删去后所有剩余子树大小最大值最小的点.

  2. 树的重心是删去后所有剩余子树大小全部小于等于\(\lfloor \cfrac{ n }{ 2 } \rfloor\)的点.

  3. 树的重心只有可能有一个或两个.

  4. 如果树有两个重心,那么这两个重心相邻.

  5. 树的重心是所有点到其距离之和最小的点.

  6. 把一个树添加或删除一个叶子,那么它的重心最多只移动一条边的距离.

  7. 把两个树通过一条边相连得到一个新的树,那么新的树的重心在连接原来两个树的重心的路径上.

(2)的证明如下:

如果重心是\(u\),且删去\(u\)后剩余最大子树大小大于\(\lfloor \cfrac{ n }{ 2 } \rfloor\),设这棵子树中与\(u\)相邻的点为\(v\),则我们删去\(v\)后,最大子树大小一定会减少,不满足假设,所以(2)得证.

另外,如果一个点删去后所有剩余子树大小全部小于等于\(\lfloor \cfrac{ n }{ 2 } \rfloor\),那它也一定是重心.因为不存在除了重心以外的满足条件的点:考虑调整法,与重心相邻的点一定都不满足条件,因为它们的子树大小全都小于等于\(\lfloor \cfrac{ n }{ 2 } \rfloor\),移动后最大子树一定不小于\(n - \lfloor \cfrac{ n }{ 2 } \rfloor\).

(3)(4)的证明如下:

首先证明:如果有两个点都是重心,那它们一定相邻.

考虑如果二者不相邻,那删去它们后剩下的最大子树大小一定相等,设这两个点分别为\(x , y\),那删去\(x\)后,剩下的最大子树一定包含了\(y\),而这个子树的大小一定小于等于\(\lfloor \cfrac{ n }{ 2 } \rfloor\).那删去\(y\)后,剩下的最大子树大小必定大于\(\lfloor \cfrac{ n }{ 2 } \rfloor\),一定不合法.

而树上不可能有超过两个点两两相邻,于是最多只有两个重心,且它们一定相邻.

(5)的证明如下:

考虑如果\(u\)是树的重心,我们看能不能将\(u\)调整到另一个点使得所有点到其距离之和更小.

由于调整是一步一步做的,显然只需要判断所有和\(u\)相邻的点是否符合条件即可.设这个点为\(x\),那我们把\(u\)改为\(x\),会使答案减小\(siz_x\),增加\(n - siz_x\),由于\(siz_x \leq \lfloor \cfrac{ n }{ 2 } \rfloor\),所以这么做一定不优.

(6)的证明如下:

首先,如果加入一个叶子节点后,各个子树大小仍然都\(< \lfloor \cfrac{ n }{ 2 } \rfloor\),那显然不必调整.

不然,显然是往叶子节点移动一格或者加入一个相邻的重心.

(7)的证明如下:

不妨设两棵树大小分别为\(siz_a \leq siz_b\),然后令相连的两个点是这两棵树的根.

对于\(b\)中的重心,肯定是会往根跳,并且不可能跳出\(b\)原本的树.

Example1([CSP-S2019]树的重心)

首先取重心\(rt\)为根,如果有两个就随便取一个.

接下来我们考虑对于每个点\(x\),它在什么情况下会成为重心.首先,删掉的边不可能在\(x\)的子树内,不然一定不可能取到\(x\)的.然后,我们假设删掉的子树大小为\(S\),\(x\)的子树内最大的一个子树大小为\(g_x\),那么根据重心的性质有:

$$ \[\begin{aligned} 2 ( n - S - siz_x ) & \leq n - S \\ 2 g_x & \leq n - S \\ \end{aligned}\]

$$

整理得到:

\[ 2 g_x \leq n - S \leq 2 siz_x \]

考虑这个怎么计算:如果没有删边必须在\(x\)子树外的限制,那显然可以直接遍历一遍存下\(n - S\),然后统一使用值域树状数组做.而我们接下来考虑删去\(x\)子树内的贡献,类似colorful tree的做法,每次dfs到一个点,记录下来当前树状数组的答案,然后dfs子树,回溯时拿新答案减去旧答案就是子树内的答案.

接下来我们需要考虑\(x = rt\)怎么做.

考虑\(x\)的子树中最大的那个和次大的那个,如果我们删去的节点不在最大的子树中,那只需要保证最大的子树大小满足条件;不然,只需保证次大的子树大小满足条件,也是好维护的.

树的结构的维护

Example1

给定一棵树,树上点有点权\(val\).现在有一个值\(sum\),初始为\(0\).从\(1\)号点出发,每第一次到一个点\(u\),就会使\(sum + = val_u\).求在时刻保证\(sum \geq 0\)的前提下,\(sum\)最终的最大值.

首先注意到为了保证\(sum \geq 0\)这个性质,一个节点应该有两个值:\(lim\)表示能走到这个点所需要的最小的\(sum\),\(val\)表示到了这个点后能获得的价值.显然如果\(val \leq 0\)则无意义.

如果我们能一开始处理出根的所有儿子的\(lim\)\(val\),我们就可以使用先走\(lim\)小的点,并不断累计\(sum\)的方式做.

所以考虑不断向上合并信息.不难发现此时一个点要处理出多对\(( lim , val )\).考虑用一个左偏树维护这个东西.

但是,我们还需要保证不能跳着选点.也就是说我们要保证选中一个点,这个点的父亲必须选,怎么办呢?

一个方式是,我们把排序方法从只看\(lim\)变成先判是否存在祖先后代关系,再判断\(lim\).

另一个方式是,我们每次直接把当前子树根节点扔到堆顶.但是需要满足堆的性质.不难发现如果这个点\(val < 0\),我们可以将它与下面的\(lim\)最的节点合并直到这个点\(val \geq 0\).而如果这个点的\(lim\)太大,我们同样可以合并.注意到这样我们采取了一种很聪明的方式维护了树的形态.

dfs树的性质

Example1([CF1361E]James and the Chase)

如何判断一个点是否是好的呢?首先,如果要求是任意路径,那一个点是好的当且仅当它是一个叶向有根树的根.

现在要求是简单路径,那也就是说如果走了重复点是可以忽略的,这也就是说这个叶向有根树可以有反走边,而显然不能有横插边.不难发现这是充要条件.

另一个问题是:如何快速判断一个点是否满足上述条件呢?首先我们求出以一个好的点为根的dfs树(随机选取一定数量的点,如果一个都不是好点直接输出\(- 1\)),然后我们发现:一个点\(u\)是好的必要条件是它的子树内只有一条反走边,证明显然.假设\(u\)通过这条反走边走到了点\(v\),那么\(u\)是好的点当且仅当\(v\)也是好的点.

这是为啥呢?首先,因为我们是以一个好点为根跑的dfs树,所以\(u\)走到子树内的点必定只有一种方式.那子树外的点呢?走到\(v\)后,显然就要从它走到其它点,而它到\(u\)的子树内显然只有一种方案,那如果\(v\)到其它点也只有一种方案,那么根据\(u \rightarrow v\)这条路径,\(u\)显然也是好点.

Example2(Loj 6276)

找到所有颜色相同的点对\(( x , y )\),经过它们的路径都不合法,显然经过它们的路径可以用dfs序刻画成矩阵,最后要求矩阵面积并.

圆方树的性质

  1. 对于任意的非空无向图\(G\),一定存在一个\(G\)的点双连通分量\(B\),使得\(B\)中只有不超过\(1\)个节点是\(G\)的割点.其中,若\(B\)中没有\(G\)的割点,则有\(B = G\).

  2. 若一个点双连通分量不为\(K_2\),则该点双连通分量中至少有一个简单环.

  3. 在仙人掌上的每个点双连通分量要么是\(K_2\),要么是一个简单环.

  4. 对于一个不是\(K_2\)的点双连通分量中的任意一个点\(u\),一定存在一个简单环\(C\)使得\(u\)\(C\)上.

  5. 对于一个不是\(K_2\)的点双连通分量中的任意两个点\(u , v\),一定存在一个简单环\(C\)使得\(u , v\)\(C\)上.

  6. 对于一个不是\(K_2\)的点双,任给一点\(x\)和一边\(e\),一定存在经过\(x , e\)的简单环.

  7. 对于一个不是\(K_2\)的点双,任给两点\(s , t\)和一边\(e\),一定存在一条\(s - e - t\)的简单路径.

(6)的证明非常变魔术,你考虑把\(e : u \leftrightarrow v\)这条边给改成\(u \leftrightarrow w \leftrightarrow v\),然后\(w\)\(x\)在一个简单环上,意味着\(u , w , v , x\)在一个简单环上.

(7)考虑(6)就行,先找到\(s\)\(e\)所在的简单环,然后从这个环上连到\(t\).

任意图的性质

  1. 若一张无向连通图\(G\)中存在\(3\)个不同的一度点\(x , y , z\),则一定存在一个点\(u \notin \{ x , y , z \}\)使得存在\(3\)条两两没有公共边的简单路径满足其中一个端点均为\(u\) 且另一个端点分别为\(x , y , z\).(证明考虑求生成树后讨论LCA)

dsu on tree

Example(QOJ5020)

我们考虑树链剖分,这样将问题转化为三部分:

  1. 对于某个点而言,到它距离\(\leq d\)的点数量.这个问题可以使用点分治解决.

  2. 对于某条重链的上半部分而言,它连接的所有轻子树中,到它距离\(\leq d\)的点数量.这个问题直接dsu on tree.

  3. 对于某个点而言,在它子树内到它距离\(\leq d\)的点数量.这个问题也可以直接dsu on tree.

为什么转化为三个部分就能求解呢?我们考虑一条链\(u \rightarrow w \rightarrow v\),其中\(w\)是这条链上深度最浅的点.那么首先我们统计在\(w\)子树外的,这一个部分可以由(1)和(3)做差求出来.然后我们要求的就是在\(w\)子树内,到这条链的距离\(\leq d\)的点的数量.这个怎么求呢?我们考虑差分,求一下\(1 \rightarrow u\)\(1 \rightarrow w\)的答案然后做差.这样我们对这条到根的路径重链剖分,只需要处理重链的上半部分以及两条重链的连接处.不难发现两条重链的连接处会被多算一次,拿(3)减一下就好.以及这条路径所叉出去的重儿子也需要用(3).

现在的问题在于怎么求(2)和(3),先考虑(2),我们对于每一条重链从顶端走到低端不断地加入轻儿子,然后维护BIT就行.(3)是类似的,只不过是需要从底端走到顶端.

注意如果把重儿子和轻儿子分开处理,那么可能会在一些奇怪的地方算重,解决方法是特判\(w\)处的答案,然后拆成两条互相之间完全没有影响的链,当然这也有可能会发生跳重链的时候轻儿子算重的情况,同样需要判断一下.

最小生成树

Example1(CF1550F Jumping Around)

首先考虑离线.注意到每次肯定跳到一个自己能跳到的点,而这个点应该是所需灵活度最小的点.

考虑boruvka算法,建立最小生成树并判断.

Kruskal重构树

最小生成树时,每一次加边的时候把那个边变成虚点,两个点连到这条边上.任意两个点的LCA就是它们路径上的最小边权.

最短路

Example1(CF1753D The Beach)

首先,自然的想法是把格子图黑白染色.

然后,我们注意到一个床是不可能被移动两次及以上的.因为如果是横着动两次,那不动自然就有一对空位置了;如果是转两次,考虑转的目的一定是为了空出某个位置或某两个位置(不可能为了空出三个位置,显然这么做很闲),一次操作足矣;如果是动一次转一次也是一样的,要么转的很闲要么原本就存在这么一对空位置.

我们再进行一步转化,考虑把动床改为动格子.换句话说,每个格子可以通过一定的代价移动到和它相邻的床的与它不相邻的那个位置上.注意到移动格子的过程只会把黑格子移动到黑格子,白格子移动到白格子.

于是建立超级源点跑两边最短路,枚举最后床放在哪里即可.不过这里有一点是一个床有没有可能被黑白最短路同时跑了一遍,是有可能的,但这么跑一定不优秀,不可能是最小答案.

Example2([CF843D]Dynamic Shortest Path)

注意到\(O ( nq )\)能过.而且每次修改只是对于若干条边\(+ 1\),自然想到每次修改完后跑01bfs.

但是怎么跑呢?注意到维护每个点最短路的增量,并且在路径的增量上跑01bfs,自然可求.

Example3 同余最短路([luoguP2371]墨墨的等式)

因为\(a_i\)无序,假设\(a_1\)最小,那么所有的数字都可以按\(\mod a_1\)的结果分成\(a_1\)类.我们按照余数设置\(a_1\)个点,编号为\(0\)\(a_1 - 1\).

\(dis_i\)为所有能组成的数中且\(\mod a_1\)余数为\(i\)的最小数.那么,所有能表示出来的\(\bmod a_1\)余数为\(i\)的数都可以写作\(dis_i + k \times a_1 , k \in \mathbb{ N }\)的形式,求得\(dis_i\)后可以很轻易算出.

那么怎么求\(dis_i\)呢?我们考虑:对于任意一个数\(k\),它可以怎么得到.注意到如果\(k - a_j\)(其中\(i \ne j\))可行,那么\(k\)一定可行.自然有:\(dis_i = \min \{ dis_j + a_k | 0 \leq j < a_i , k \ne i \}\).

这显然是一个最短路问题.

差分约束

Example1([AGC056C] 01 Balanced)

\(1\)看成\(- 1\),\(0\)看成\(+ 1\),不难发现字典序最小也就是让前缀和序列字典序最小,并且有\(sum_{ r_i } = sum_{ l_i - 1 }\)以及\(- 1 \leq sum_{ i } - sum_{ i - 1 } \leq 1\),然后做\(01\)bfs跑最短路,显然最短路可以保证每个\(sum\)都尽可能小.

然后另一个问题在于这玩意为啥不会让\(sum_i = sum_{ i - 1 }\),这个建图后观察一下就知道不会发生这种情况.

2-SAT

Example1(CF1697F)

对每个点建立\(k\)对点表示\(a_i \geq x\)\(a_i < x\),就能做了.

Example2(2021集训队互测 序列)

注意到如果\(a_i < x\),那么\(a_j \geq x \land a_k \geq x\),这样就可以刻画所有的条件.

而且一定可以刻画所有的条件.

对偶图

Example1([CSP-S 2021] 交通规划)

先考虑如果附加点的颜色全都相同,那肯定输出\(0\)即可.

考虑附加点的数量为\(2\)的时候,那显然最优情况需要将整个图分成各自联通的两部分,一部分染成黑色,一部分染成白色.可以发现这就是一个对偶图.

而如果附加点的数量很多怎么做呢?稍微思考一下

广义串并联图/三度化

定义

定义:不存在\(4\)个点使得任意两点之间存在一条简单路径,且这六条路径不在\(4\)个点之外的地方相交.

删一度点

经典问题引入:树上带权最大独立集.

首先dp是可以实现的,我们考虑是否存在贪心算法.

首先,如果不带权,我们显然可以每次选取一度点或零度点,并删去所有相连的点.这样做显然是最优的.

但怎么做带权的方法呢?我们注意到可以先删掉所有负点权的点,然后可以加入剩下的所有零度点.

那么对于一度点呢?对于一个一度点\(u\)和它的相邻点\(v\),我们不能盲目选\(u\)的原因是可能选取\(v\)会更优秀.考虑做一个带悔贪心,我们先把\(u\)选上,然后把\(v\)的权值设为\(val_v - val_u\),相当于我们仍然可以选\(v\),但是要花费\(val_u\)的代价把\(u\)删去.

我们把类似这样的操作称为删一度点.

缩二度点

问题引入:给定一个仙人掌,每个点可以染色为\(0\)\(1\),\(u\)节点染成\(0\)会有\(b_u\)的贡献,不然有\(w_u\)的贡献.若一条边\(e\)相邻的两点颜色相同则有\(s_e\)的贡献,不然有\(d_e\)的贡献,求最大答案.

首先如果有一度点和零度点,我们仍然可以使用删一度点的操作.

如果没有,考虑仙人掌上的一个点双一定是一个简单环.而且一定存在一个点双\(B\)满足\(B\)只包含一个割点.

那么对于这个点双上的一个非割点\(x\)以及和它相邻的两个点\(u\)\(v\),我们考虑\(x\)的染色有可能改变\(u\)\(v\)的答案,那么怎么办呢?

冷静思考一下,我们想办法把\(x\)给删掉.简单来说,我们把\(u\)\(v\)之间连一条边权为\([ w_{ 0 , 0 } , w_{ 0 , 1 } , w_{ 1 , 0 } , w_{ 1 , 1 } ]\)的边,分别表示\(u\)\(v\)的染色为以上四种情况时这条边(也就是原本的\(x\))的最大贡献是什么,这显然可以通过讨论\(x\)的取值而求得.这样初始边权实际上就是\([ s , d , d , s ]\),于是我们就可以删掉一个二度点并连起来与它相邻的两个点,我们把类似这样的操作称为缩二度点.

叠合重边

注意到使用缩二度点的时候,会把一个三元环缩成两个点及链接它们的两条重边,但是我们可以直接把重边合起来,我们把类似这样的操作称为叠合重边.

正确性证明

接下来我们证明:任何广义串并联图都可以通过以上三种操作缩为一个点.

引理1

对于一个无向图\(G\),若进行若干次删一度点操作,缩\(2\)度点操作以及叠合重边操作后得到的图不是广义串并联图,那么\(G\)也不是广义串并联图.

考虑用逆操作还原原图.删一度点的逆操作是加入一个点,叠合重边的逆操作是将一条边变成两条边,这两个操作显然不会使一个不是广义串并联图的图变成广义串并联图.接下来考虑缩二度点的逆操作:删掉一条边\(( u , v )\)并加入一个点\(w\)和两条边\(( u , w )\)\(( w , v )\).

由于这个图不是广义串并联图,所以一定存在一组反例点\(\{ a , b , c , d \}\).如果我们删掉的边不在作为反例的六条边上,那显然不影响;如果在,由于新加入的两条边仍然可以作为路径,所以也不影响.

于是引理得证.

引理2

任意一张所有点的度数都大于等于\(3\)的简单无向连通图,一定不是广义串并联图.

这个引理的严格证明有些麻烦.我们冷静一下,一个四个点的完全图满足以上条件且不是广义串并联图.而其他的图感性理解一下应该可以通过缩路径的方式变成一个四个点的完全图.

结合引理1,我们得知任意一个操作后不能变成单个节点的图的无向连通图不是广义串并联图.

引理3

任意一个满足\(m \leq n + k\)的图,通过删一度点,缩二度点,叠合重边操作后,\(m\)\(n\)都会到达一个\(O ( k )\)的量级.

考虑缩完点后,所有点的度数\(\geq 3\),于是有\(2 m \geq 3 n\),而在操作过程中,\(m - n\)的值显然是不增的,于是有\(m - n \leq k\),解一下方程得到\(n \leq 2 k , m \leq 3 k\).

Example1(22zr提高十连测day6摆件)

首先考虑颜色之间没啥区别,所以对于一棵树来说,朴素的dp是可以的.

简单来说,设\(dp_i\)表示第\(i\)棵子树的答案.合并的时候考虑设\(f_v = \cfrac{ 1 }{ k } dp_v sam_e + \cfrac{ k - 1 }{ k } dp_v dif_e\),自然有\(dp_u = \prod_{ u \rightarrow v } f_v \\\).

接下来考虑先随便找一棵生成树,然后暴力枚举多余的反走边的深度较低的叶子节点的颜色,再进行dp即可.

另外也可以缩点后做,不过对于这题没啥区别.

Example2([JOI Open 2022] 放学路)

广义串并联图的一个很重要的思想是:我们通过一些手段改变这个图的形态为一个好做的形态,但是答案又和原图相同.

在这个思想的指导下,我们考虑这个题能否进行三度化.不过注意起点和终点简单特判一下,别把他们给删了.这样我们最后如果得到了一个只有起点和终点的图,那就一定是no.

然后如果没有只得到起点和终点呢?对最短路图建DAG,考虑如果\(S\)\(T\)在一个点双中,我们找到两个点\(u , v\),使得\(u \rightarrow v\),并且\(u\)的出度至少是\(2\),\(v\)的入度至少是\(2\),显然只要找到就做完了.现在的问题就在于为啥这条边一定存在.这个考虑找一个入度至少为\(2\)的点\(v\),找到它的入点\(u\),如果\(u\)的出度不是\(2\),那么\(u\)也是一个入度至少为\(2\)的点.这样往前推一定至少能推到一个点(因为不可能\(S\)贡献了俩入度).

如何保证\(S , T\)在一个点双中呢?其实只需要添加一条边\(( S , T , dis_{ S \rightarrow T } )\)就行了.显然加了后不会对答案产生影响.然后不在\(S , T\)这个边双内的点也没有用了.

点分治

Example1(CFgym101002K)

点分治,假设当前分治重心是\(g\),将每个数缩成一个二元组\(( w_i , d_i )\),所求就是\(w_i w_j + d_i + d_j\)最小,直接排序做斜率优化.

点分树的性质

  1. 点分树的高度是\(O ( \log n )\)级别.

  2. 两个点在原树上的路径一定经过其在点分树上的LCA.

Example1(codechef [BTREE])

这题用到了一个经典套路:一个树形连通图的点数减去边数为\(1\),把虚树建出来,能到达一个点的守卫必然是一个树形连通图(虚树中原本没有守卫的点可以加个不同覆盖范围的守卫).于是我们只需要求出每个守卫能覆盖多少点以及两个守卫之间的那条路径能覆盖多少个点,前者用点分树轻松维护,后者的话找一下这条边上的某个满足条件的点就行.

Example2

给定一棵树,现在在上面选定\(m\)对不同的点,要求每对点的距离之和最大.

考虑如果确定了\(2 m\)个点,我们如何匹配他们.对每条边算贡献,假设这条边两侧分别有\(a , b\)个点,那么这条边最大的贡献就是\(\min \{ a , b \}\).不难发现这个上界可以取到,只需要取这\(2 m\)个点的带权重心,由于不存在绝对众数,所以直接两两匹配.枚举带权重心是啥,这样复杂度\(O ( n^2 )\).

那么怎么优化呢?我们注意到如果以一个点\(x\)作为根,而它有一个儿子\(y\),\(y\)的子树中选了少于\(m\)个点,那么我们以\(y\)为根一定是不优秀的,不然一开始就不可能只选少于\(m\)个点,再考虑带权重心这个东西,上点分树.

具体来说,我们建立点分树,然后从点分树的根开始枚举带权重心,如果当前没有一棵子树选了\(m\)个点,就停止,不然往选了\(m\)个点的那棵子树走(如果有两个的话选第\(m\)大更大的那个),这样就只会选取\(O ( \log n )\)个带权重心.

边分治

需要建立虚点转二叉树.

边分树的性质

  1. 非叶子节点代表边,叶子节点代表点.

  2. 边分树的高度是\(O ( \log n )\)级别.

  3. 边分树上每棵子树中的叶子节点一定联通.

  4. 是一棵完全二叉树.

  5. 两个点在原树上的路径一定经过其在边分树上的LCA所代表的边.

二分图

定理

最大流-最小割定理
Hall定理

对于二分图\(\langle V_1 , V_2 , E \rangle , | V_1 | \leq | V_2 |\),那么该图存在完备匹配的充要条件是\(\forall Q \subseteq V_1 , | Q | \leq | N ( Q ) |\),其中\(N ( Q )\)指的是所有与\(Q\)中点有边相连的点的集合.

必要性很显然,接下来说明充分性.设\(T\)为最小点覆盖,也就是最大匹配的数量,再设\(M\)为最大匹配,此时自然有:

\[ | M | = | T | = | T_1 | + | T_2 | \geq | T_1 | + | N ( V_1 / T_1 ) | \geq | T_1 | + | V_1 / T_1 | = | V_1 | \]

显然\(| M | \leq | V_1 |\),于是\(| M | = | V_1 |\).

另外,Hall定理有一个推论:正则二分图一定存在完美匹配.什么叫正则二分图,就是所有的点的度数(不为\(0\))都相等的图.

\(2^d\)-正则二分图求完美匹配的话,可以不断求欧拉回路并给边定向,每次把一个方向的边全都删掉,这样就转化成了\(2^{ d - 1 }\)-正则二分图,不断递归到\(d = 0\).

Vizing定理

\(f ( G )\)表示将\(G\)边染色,使得有公共点的边的颜色不同,最少需要的颜色数量.

\(\delta ( G )\)表示\(G\)中的点的最大度数.

对于一般图,我们有:\(\delta ( G ) \leq f ( G ) \leq \delta ( G ) + 1\),对于二分图有\(\delta ( G ) = f ( G )\).

考虑这个的证明:我们每次将一对点\(( x , y )\)染色,考虑设它们当前没染色的最小的颜色是\(l_x , l_y ( l_x \leq l_y )\),如果相等就直接选,不然类似增广路更新.

二分图最大权匹配

假定二分图两边两两有边(不是的话可以补上\(- \infty\)的边),这样就一定存在完美匹配.

我们给每个点一个顶标权值\(v\),对于任意一条边\(e : a \leftrightarrow b\),它的权值是\(w_e\),我们要求\(v\)满足\(v_a + v_b \geq w_e\).

如果我们规定了一组顶标后,取出所有满足\(v_a + v_b = w_e\)的边后的图(称作相等子图)存在完美匹配,那这组完美匹配就一定是最大权匹配.

这是为啥呢?考虑此时的最大权其实也就是\(\sum v\),而由于\(v_a + v_b \geq w_e\),因此最大权匹配一定不会超过\(\sum v\).这就是一个可达的上界.

那么我们该怎么得到一个相等子图呢?考虑先构造一组合法的顶标,让左部端点取边的最大值,右部端点取\(0\),然后开始增广.

从左侧任意一个非匹配点出发,在相等子图上走增广路并增广.如果增广失败,我们将访问过的左部端点全部减去\(d\),右部端点全部加上\(d\),注意到此时匹配边一定不会变化,因为匹配边要么两个端点都没被访问过,要么都被访问过.而左端点被访问过,右端点没被访问过的边有可能加入相等子图,我们考虑取所有这种边的需要的差值的最小值并进行更新.但是直接这么做的复杂度有点高.

使用bfs优化,可以发现只会扩大\(O ( n^2 )\)次子图,每次复杂度\(O ( n )\),增广的复杂度类似,于是总复杂度\(O ( n^3 )\).

Example

Example1([ XVII Open Cup named after E.V. Pankratiev. Grand Prix of Japan(openstrain contest 1489) B]Point Pairs)

看到这种要求横坐标或纵坐标相同的题,有一个自然的想法是建立二分图,对于点\(( x , y )\),将二分图左边的\(x\)和右边的\(y\)连一条边.那么配对等价于要每次找两条相邻的边删掉.那么如何删掉呢?

首先发现的是,二分图不同的连通块可以分开处理,我们接下来只讨论一个连通块的情况.如果这个连通块有奇数条边,显然一定不行.而又可以发现,如果这个连通块有一个点度数仅为\(1\),那这条边如何删是确定的,我们可以把它和另一条边删掉,不难发现怎么删最后得到的新图仍然联通.而如果不存在度数为\(1\)的点呢?由于这是一个二分图,不存在奇环,所以我们可以找一个简单环删掉,之后显然也是一个连通块.我们到这里就可以发现问题了.运用数学归纳不难证明:只要一个连通块的边数是偶数就一定合法.

然后我们可以使用可撤销的分治解决这个问题.

网络流常见模型

最大流

最小费用最大流

最小割

最大流\(=\)最小割,证明显然.

最小割求方案。这个是简单的,我们删去所有流量\(0\)的边后从\(S\)开始bfs,找到所有\(S\)能到达的点,显然这些点(注意如果这个点一开始就不能到达\(T\),那它是废物,不用管它,下面只讨论它能到达\(T\)的情况)组成一个SCC(为啥呢?首先\(S\)能到达它们,其次由于是最小割,因此这个点一定到达不了\(T\),而原本是可以到达\(T\)的,假设这个点是\(x\),那么一定是原本存在一条\(S \rightarrow x \rightarrow T\)的路径被割掉了,也就是现在一定存在一条\(x \rightarrow S\)的路径)。最小割包含的边一定是这个集合和其它集合交界处的边。这是为啥呢?首先这些边一定组成了原图的一个割,其次,我们发现割不可能存在\(S\)所在SCC中,而割掉完全不连接\(S\)的边可以发现不如割其中一个点在\(S\)所在SCC的边。

Example1(luoguP4313 文理分科)

先把所有的满意值全部吃下,然后考虑放弃哪些.

对于每个人\(u\),将\(S\)向他连一条流量为\(art\)的边,它向\(T\)连一条为\(science\)的边,表示它自己要么放弃文科,要么放弃理科.

然后再对每个点建立一个虚点\(u '\),\(S\)\(u '\)连一条为\(sameart\)的边,\(u '\)向相邻的实点连\(\infty\)的边,表示要么放弃\(sameart\),要么那些点全都放弃理科.\(samescience\)是同理的.

从这也可以看出来,大部分最小割的题目其实就是将冲突的选项放到一条路径中,然后考虑放弃哪些,将这个限制用最小割表示出来.

Example2([HNOI2013]切糕)

也是显然的最小割,唯一难处理的地方在于相差\(\leq D\).

这个怎么做呢?建图后先每一竖轴都变成了一条链,我们在链之间加一些\(\infty\)的边,使得如果断开的两个点之差大于\(D\),那就可以通过这条边破坏最小割结构.

这题同样告诉我们:对于最小割题目中的限制条件,几乎都是需要考虑破坏最小割结构的(也有可能是用费用流限制).

Example3(uoj704)

二分图最小割计数.

先求出最小割,然后显然每个匹配的三条边一定会选择一条割掉.

不妨设\(a_i = 0 / 1 / 2\)表示第\(i\)对匹配割掉了哪一条边.

考虑每个非匹配边\(( u , v )\)对点权的限制:

  1. \(u\)在最大匹配\(i\)中,\(v\)不在.则\(a_i = 0\).

  2. \(v\)在最大匹配\(i\)中,\(u\)不在,则\(a_i = 2\).

  3. \(u\)在最大匹配\(i\)中,\(v\)在最大匹配\(j\)中,则\(a_i = 0\)\(a_j = 2\).

前两种是好处理的,考虑第三种:显然所有都选\(2\)或所有都选\(0\)是一种方案,更进一步地,我们将\(i \rightarrow j\),那么在一个强连通分量中的点一定都是\(2\)或都是\(0\).这样可以缩点,缩点后发现DAG上的每一条路径的染色都形如\(0 , 0 , 0 , \cdots , 0 , ( 1 ) , 2 , \cdots , 2 , 2 , 2\).

不妨折半搜索,按照拓扑排序,确定前一半哪些是\(0\),剩下是\(1 / 2\),那他们的后继必然全都是\(2\),这样后面的是\(2\)的集合一定是这个后继集合的超集,高维后缀和.

接下来只需要判断哪些位置可以选\(1\).相当于前驱全都是\(0\)并且后继全都是\(2\).

二分图匹配

二分图最小点覆盖

二分图最小点覆盖\(=\)二分图最小割.

问题在于如何求解方案.

我们从左侧的非匹配点开始dfs,走还有残留流量的路径.并将路径上所有的点全都打上标记.那么左侧所有的未标记点和右侧所有的标记点就是一组合法的方案.

这是为啥呢?首先我们注意到,左侧的非匹配点一定会被标记,右侧的非匹配点一定不会被标记.

为啥右侧的非匹配点一定不会被标记呢?因为如果被标记了,从左侧非匹配点到右侧非匹配点这条路径的起始边和终边就都是非匹配边,显然是一条增广路.

然后我们又注意到:对于一组匹配点,要么两者都被标记,要么两者都不被标记,因为一旦走到了右侧点,下一步必然走向左侧点.而如果走到了左侧点,也必然是从右侧点走过来的.

接下来我们讨论一下:

对于非匹配边,由于其必然连了一个左侧非匹配点,所以它的右边必然被选择了.

对于匹配边,不难发现它会被某个匹配点覆盖掉.

于是得证.

当然,上面的证明略显啰嗦.事实上我们这么考虑:

首先,我们按照套路,求出\(S\)所有能到达的点.根据二分图的性质,这个点的集合必然不包括\(T\).

然后我们取所有不在这个点集的左侧点和所有在这个点集的右侧点,这样所有的点被分为了四个部分,边也自然被分为了四个部分,讨论一下就知道这四个部分中有一个部分是不存在边的.于是得证.

二分图最大独立集

二分图最大独立集\(= n -\)二分图最小点覆盖.

Example1(CF1404E)

在两个可选矩形的边界处建立一个点,如果它被选了,那么说明这个矩形和上面那个矩形被一起覆盖了.然后注意到每有一个点被选,自然就多覆盖了一个矩形,显然一个矩形不可能又跟纵向的一起被覆盖又跟横向的一起被覆盖,在他俩之间连边跑最大独立集即可.

感觉还是类似于最小路径覆盖,将这种两个一起被覆盖就减少答案的东西转换成一整条流.

最大权闭合子图

原图的边流量设为\(+ \infty\),然后对于每个点\(x\),如果\(val_x > 0\),那么\(ans + = val_x\),然后将\(S \rightarrow x\),流量为\(val_x\);不然,\(x \rightarrow T\),流量为\(- val_x\),然后求出最小割\(w\),答案即为\(ans - w\).

Example1(luoguP4177)

只需要把中间的\(\infty\)边改为租用的代价即可.

最小路径覆盖(覆盖点)

将每个点\(x\)拆为两个点\(A_x\),\(B_x\),将\(S\)向所有\(A\)连边,\(B\)\(T\)连边,如果图中存在一条路径\(x \rightarrow y\),则连边\(A_x \rightarrow B_y\),流量均为\(1\),然后求出最大流\(w\),答案即为\(n - w\).

还有一个版本是可以重复走点,做一遍传递闭包就行.因为可重复相当于原图上的可跳点,这个版本又叫最小链覆盖.

Example1([网络流24题]魔术球问题)

枚举球数,不断在残联网络上加边并在新图跑最小路径覆盖即可.

最长反链

反链是一个点的集合,满足这个集合中的点两两不可达.

最长反链\(=\)可重复走点的最小点覆盖(最小链覆盖).

为啥呢?因为发现做完传递闭包后等价于新图的最大独立集.当然图是有性质的,观察一下可重复走点的最小点覆盖就可以发现等价于传递闭包后在二分图上求最大独立集.

Example1([CF1630F]Making It Bipartite)

首先显然的一点是,对于任意一个数字\(x\),这个序列中不能同时出现\(px\)\(pqx\),其中\(p , q\)都是大于等于二的正整数.这是显然的.如果我们把图改为有向图,由\(x \rightarrow px\),那么整个图就只会有两种点:只有出边的点和只有入边的点.

那么我们该怎么办呢?如果是只能出现\(x\)就不能出现\(px\),那这就是一个经典的最长反链问题.但多了一层,我们可以考虑类似分层图的思想:建立和原图完全一样的图\(G '\),并且将\(G\)中的\(x\)\(G '\)中的\(x '\)连有向边,然后跑最长反链.不难发现这样做是正确的.

平面图最小割

平面图最小割\(=\)对偶图最短路.

最小费用任意流

一般费用流,但是当当前增广路代价为正的就停止增广.

和最小费用最大流不一样,这玩意是可以增量的.

只需要考虑所有新的从源到汇的增广路以及增加过程出现的负环即可.

Example1(luoguP4694 [PA2013]Raper)

费用流模型很好建立,问题在于这个东西好像跑费用流有点慢.

那咋办呢?我们考虑到费用流是有凸性的.所以搭配一下wqs二分.

然后分一下三种情况讨论:

  1. 直接\(S \rightarrow T\)的负增广路,相当于选取最小的\(b\)和当前的\(a\)搭配.

  2. 有一条\(S \rightarrow a \rightarrow b \rightarrow a \rightarrow S\)的负环,相当于以当前的\(a\)代替前面的某个较大的\(a\).

  3. 有一条\(S \rightarrow a \rightarrow b \rightarrow T \rightarrow b \rightarrow a \rightarrow S\)的负环,注意到这个环必然没意义,因为不可能存在一条\(T \rightarrow S\)的负路径(不然反路径就是正的,而最小费用任意流不可能流正路径),所以这种情况不如直接选\(S \rightarrow T\)的路径.

讨论完拿堆模拟一下就行.

这引出了著名的模拟费用流算法.

负费用最小流

一般费用流,但是当增广当前增广路时费用变成正的就停止增广.

注意如果两条增广路代价相同选流量大的那条.

有负环的费用流

首先注意到:如果初始图没有负环,那无论后面怎么流都不可能出来负环.因为这意味着要么是一开始流了个正环,要么是一开始有负路径不走走正路径,都不太可能.

对于所有的负边\(u \rightarrow v\),我们建立两个新点\(S '\)\(T '\),我们先将这条负边反向权值取相反数并让答案加上\(f \times v\),之后令\(u \rightarrow T ' , S ' \rightarrow v\),跑\(S ' \rightarrow T '\)的费用流,这个时候再在残联网络上跑\(s \rightarrow t\)的费用流就是答案.

为啥会这样呢?

首先先证明正确性,这个东西相当于一开始跑了一下\(T ' \rightarrow u \rightarrow v \rightarrow S '\)的图.然后我们在跑\(S ' \rightarrow T '\)的时候一定是可以把上面的那个东西所从\(T ' \rightarrow S '\)的所有流量全都退回去,因为这是一个可以构造的上界.也就相当于我们跑了一个环流.而在费用流里跑环流显然是不会影响答案的.

好,那么为啥这么做就不会出现负环了呢?因为你不可能在跑\(S ' \rightarrow T '\)的时候跑个正环出来,自然不可能出现负环.

另外有一点是,一个点可能向\(S '\)\(T '\)连很多边,其实是可以拼掉的,因为这些边全都是零权边,而构造完后的图是非负权边.

模拟费用流

对于特殊的图,模拟EK费用流的增广过程并进行操作.

对着例题记吧.

Example1(luoguP4694 [PA2013]Raper)

散题

Example1([CQOI2014]危桥)

有一个朴素的想法是:我们直接按题意建图,然后\(S \rightarrow a_1 , b_1\),\(T \rightarrow a_2 , b_2\),跑最大流然后检查是否满流.

问题在于,这样有可能会出现\(a_1 \rightarrow b_2\)的流量,我们怎么避免这种情况呢?

做法是,我们交换\(b_1 , b_2\)并重复上面的过程,如果还是满流,我们声明一定合法.

为什么呢?我们注意到此时网络上的流量分为四种:\(a_1 \rightarrow a_2\),\(a_1 \rightarrow b_2\),\(b_1 \rightarrow a_2\),\(b_1 \rightarrow b_2\).不难发现\(a_1 \rightarrow b_2\)\(b_1 \rightarrow a_2\)的流量是相等的.

在第二次跑网络流时,我们不妨直接将\(a_1 \rightarrow a_2\)\(b_2 \rightarrow b_1\)的流量加入答案并将这两条路径反向.此时,如果\(a_1\)还是要走到\(b_1\),你发现第一轮的时候已经找到了一条\(b_1 \rightarrow a_2\)的路径,我们一定可以走这条来构造出只有\(a_1 \rightarrow a_2\)的路径,另一边同理.

图的计数问题

Prufer序列

我们可以将一颗有编号\(n\)个点(\(n \geq 2\))的无根树与一个长度为\(n - 2\)的Prufer序列建立双射.换句话说,一颗有编号\(n\)个节点的无根树总共有\(n^{ n - 2 }\)种(Cayley公式).

首先证明一个树可以对应到一个序列:每次选择一个度数为\(1\)的编号最小的点,把它连向的点加到序列中并把这个点删去,直到最后只剩下两个节点,这样我们就把一棵树对应到一个序列.不难发现每个点出现的次数是其度数\(- 1\).

然后证明一个序列可以还原成一棵树:

我们可以通过序列得知每个点的度数,每次找到度数中最小的那个点并把它与序列中的第一个元素连边并删去序列中的第一个元素,不断这么做显然可以还原树.

Example

一个\(n\)个点的图有\(k\)个连通块,现在加入\(k - 1\)条边使得图连通,求方案数.

\(s_i\)为第\(i\)个连通块的点数,\(d_i\)为第\(i\)个连通块所新连上的边数,如果我们令\(\binom{ n }{ c_1 , c_2 , . . . , c_m } = \cfrac{ n ! }{ c_1 ! c_2 ! . . . c_m ! } , \sum_{ i = 1 }^m c_i = n \\\),也即将\(n\)个位置拆分成\(m\)个集合,第\(i\)个集合有\(c_i\)个位置的方案数.

那我们所需要做的也就是枚举每个连通块所新连出的边数\(d_i\),于是答案即\(\sum_d [ \sum d_i = 2 k - 2 ] \binom{ k - 2 }{ d_1 - 1 , d_2 - 1 , . . . , d_k - 1 } \prod_{ i = 1 }^k s_i^{ d_i } \\\).

注意到我们有多项式定理:\(( x_1 + x_2 + . . . + x_m )^n = \sum_{ c } [ \sum c_i = n ] \binom{ n }{ c_1 , c_2 , . . . , c_m } \prod_{ i = 1 }^m x_i^{ c_i } \\\).

于是原式\(= n^{ k - 2 } \prod_{ i = 1 }^k s_i\).

Prufer序列的矩阵树定理理解

事实上,Prufer序列其实是可以拿矩阵树定理代替的(但是更麻烦一点).

我们先考虑证明Cayley公式:构造矩阵:

\[ \begin{bmatrix} - n + 1 & 1 & \cdots & 1 \\ 1 & - n + 1 & \cdots & 1 \\ \vdots & \vdots & \ddots & \vdots \\ 1 & 1 & \cdots & - n + 1 \end{bmatrix} \]

其主余子式为:

\[ \begin{bmatrix} - n + 1 & 1 & \cdots & 1 \\ 1 & - n + 1 & \cdots & 1 \\ \vdots & \vdots & \ddots & \vdots \\ 1 & 1 & \cdots & - n + 1 \end{bmatrix} \]

将所有行全部加到第一行:

\[ \begin{bmatrix} - 1 & - 1 & \cdots & - 1 \\ 1 & - n + 1 & \cdots & 1 \\ \vdots & \vdots & \ddots & \vdots \\ 1 & 1 & \cdots & - n + 1 \end{bmatrix} \]

全部加下来,然后就成了上三角矩阵,将对角线乘起来就是\(n^{ n - 2 }\).

连通块的结论是类似的.

LGV引理

\(G\)是一个有限的带权有向无环图,有点集\(V\)的一个大小为\(n\)的子集\(A = \{ a_1 , a_2 , . . . , a_n \}\)作为起点集合,一个大小为\(n\)的子集\(B = \{ b_1 , b_2 , . . . , b_n \}\)作为终点集合.

记边\(i\)的权值为\(w_i\).对于有向路径\(p\),记路径上所有边的边权的乘积为\(W ( p )\).记\(e ( u , v ) = \sum_{ p : u \rightarrow v } W ( p )\),即从\(u\)\(v\)的所有路径的边权乘积之和.

\(P : A \rightarrow B = ( p_1 , p_2 , . . . , p_n )\),\(p_i\)表示从\(a_i\)\(b_{ \sigma ( i ) }\)的一条路径,其中\(\sigma\)是一个排列,记\(sign ( \sigma )\)\(- 1\)以这个排列的逆序对数量为幂的值.又记\(\sigma ( P )\)\(P\)所对应终点的排列.若满足\(\forall 1 \leq i , j \leq n , i \ne j\),\(p_i\)\(p_j\)没有公共点,则记作\(P^u\),否则记作\(P^c\),若不作区分记作\(P\).记\(W_{ all } ( P ) = \prod_{ i = 1 }^n W ( p_i ) \\\),也就是所有路径的乘积.

设矩阵\(M\)满足\(M_{ i , j } = e ( a_i , b_j )\),那么有:

\[ \det M = \sum_{ P^u : A \rightarrow B } sign ( \sigma ( P^u ) ) W_{ all } ( P^u ) \]

证明:

根据行列式的定义,我们有:

$$ \[\begin{aligned} \det M & = \sum_{ \sigma } sign ( \sigma ) \prod_{ i = 1 }^n e ( a_i , b_{ \sigma ( i ) } ) \\ & = \sum_{ \sigma } sign ( \sigma ) \prod_{ i = 1 }^n \sum_{ p_i : a_i \rightarrow b_{ \sigma ( i ) } } w ( p_i ) \\ \end{aligned}\]

$$

考虑后面那部分,\(\prod_{ i = 1 }^n \sum_{ p_i : a_i \rightarrow b_{ \sigma ( i ) } } w ( p_i ) \\\)形如一个卷积的形式,所以这个式子等价于所有对应排列为\(\sigma\)\(P\)\(w ( P )\),所以有:

\[ \begin{aligned} \det M & = \sum_{ \sigma } sign ( \sigma ) ( \sum_{ P : \{ a_1 , . . . , a_n \} \rightarrow \{ b_{ \sigma ( 1 ) } , . . . , b_{ \sigma ( n ) } \} } w ( P ) ) \\ & = \sum_{ P : A \rightarrow B } sign ( \sigma ( P ) ) w ( P ) \\ & = \sum_{ P^u : A \rightarrow B } sign ( \sigma ( P^u ) ) w ( P^u ) + \sum_{ P^c : A \rightarrow B } sign ( \sigma ( P^c ) ) w ( P^c ) \end{aligned} \]

接下来只需证明\(\sum_{ P^c : A \rightarrow B } sign ( \sigma ( P^c ) ) w ( P^c ) = 0 \\\)即可.

设所有\(P^c\)组成的集合为\(E\),考虑构造一个映射\(f : E \rightarrow E\)满足如下条件:

  1. \(f ( P^c ) \ne P^c\).

  2. \(f ( f ( P^c ) ) = P^c\).

  3. \(w ( f ( P^c ) ) = w ( P^c )\).

  4. \(sign ( f ( P^c ) ) = - sign ( P^c )\).

上面的结论即得证.

我们不妨考虑\(P^c\)中的第一对相交的路径\(p_i\)\(p_j\),并交换它们的终点.显然满足上述条件,于是结论得证.

Example

现在有\(n\)个点,第\(i\)个点位于\(( a_i , 1 )\),需要走到\(( b_i , n )\).一个在\(( x , y )\)的点可以走向\(( x + 1 , y )\)\(( x , y + 1 )\).求路径不相交的方案数.

路径不相交,则终点排列只有可能是\(\{ 1 , 2 , . . . , n \}\),直接使用LGV引理即可.

矩阵树定理

无向图情况

定义无向图的度数矩阵\(D ( G )\)为:\(D ( G )_{ i , j } = \begin{cases}0 & i \ne j \\ \deg_{ i } & i = j\end{cases}\).

\(w ( i , j )\)\(i\)\(j\)之间直接相连的无向边个数,定义无向图的邻接矩阵\(A ( G )_{ i , j } = \begin{cases}0 & i = j \\ w ( i , j ) & i \ne j\end{cases}\)

定义无向图的基尔霍夫矩阵(又称拉普拉斯矩阵)\(L ( G ) = D ( G ) - A ( G )\).

\(t ( G )\)为图\(G\)的生成树个数,那么有:\(t ( G )\)等于基尔霍夫矩阵任意一个主余子式.

引理:无向图的基尔霍夫矩阵的任意一个代数余子式都相等.

证明:考虑删去第\(i\)行,设剩下的矩阵为\(A = [ \vec{ r }_1 , \vec{ r }_2 , . . . , \vec{ r }_n ]\),根据基尔霍夫矩阵的性质,不难发现\(\sum{ \vec{ r }_i } = \vec{ 0 }\).\(\forall 1 \leq j < k \leq n\),如果我们删去第\(j\)列,考虑将除了第\(k\)列的其它列全部加到第\(k\)列,于是得到矩阵\([ \vec{ r }_1 , . . . , \vec{ r }_{ j - 1 } , \vec{ r }_{ j + 1 } , . . . , \vec{ r }_{ k - 1 } , - \vec{ r }_j , \vec{ r }_{ k + 1 } , . . . , \vec{ r }_n ]\).我们接下来一路将第\(k\)列交换到第\(j + 1\)列之前并取反,我们就得到了删去第\(k\)列的矩阵,于是有\(M_{ i , j } = ( - 1 )^{ 1 + ( k - 1 ) - ( j + 1 ) + 1 } M_{ i , k }\),也就是\(C_{ i , j } = C_{ i , k }\),同理可证明\(C_{ j , i } = C_{ k , i }\).

接下来,用\(T\)表示生成树的边的集合,设\(w ( T ) = \prod_{ e \in T } w ( e )\),我们只需证明\(C_{ 1 , 1 } = \sum w ( T )\).

定义\(\zeta ( e , u ) = v , e = \{ u , v \}\),考虑构造一个\(n \times m\)的矩阵\(A\)满足\(A_{ i , j } = \begin{cases}1 & i \in e_j \land i < \zeta ( e_j , i ) \\ - 1 & i \in e_j \land i > \zeta ( e_j , i ) \\ 0 & other\end{cases} \\\).

注意到:

$$ \[\begin{aligned} AA^T ( i , j ) & = \sum_{ k = 1 }^m A ( i , k ) A^T ( k , j ) \\ & = \sum_{ k = 1 }^m A ( i , k ) A ( j , k ) \\ \end{aligned}\]

$$

\(i = j\)时,不难发现\(AA^T ( i , j ) = \sum_{ k = 1 }^m [ i \in e_k ] = \deg_i\).不然,注意到显然为\(- \sum_{ k = 1 }^m [ i \in e_k ] [ j \in e_k ]\).也就是说,\(AA^T = L\).

定义\(A\)删去第一行后得到的矩阵为\(B\),则\(BB^T = M_{ 1 , 1 }\).此时我们带入Cauchy-Binet公式,得到:

\[ \begin{aligned} M_{ 1 , 1 } & = \sum_{ | S | = n - 1 , S \subseteq \{ 1 , 2 , . . . , m \} } \det ( B [ S ] B^T [ S ] ) \\ & = \sum_{ | S | = n - 1 , S \subseteq \{ 1 , 2 , . . . , m \} } \det ( B [ S ] )^2 \end{aligned} \]

接下来我们需要证明:如果\(S\)集合构成了一棵生成树,那么\(\det B [ S ] = \pm 1\).反之,\(\det B [ S ] = 0\).

如果集合没有构成一个生成树,则至少存在一个简单环.如果有某个点是孤立点那么答案肯定是\(0\),因此只需考虑每个点都与边连通的情况即可.

考虑这种情况下,如果有两条边\(( u_1 , u_2 )\)\(( u_2 , u_3 )\)被选上了,那么我们可以通过列变换将它们改为\(( u_1 , u_2 )\)\(( u_1 , u_3 )\).这样不断进行下去,如果存在环,一定会出现重边选择的情况,这个时候行列式的值为\(0\).如果不存在环,那么我们可以通过这个操作得到一个菊花图.所以行列式为\(\pm 1\).

所以定理得证.

Example([省选联考 2020 A 卷]作业题)

给定一个图,设第\(i\)条边的权值为\(w_i\),求所有生成树的\(\gcd ( w_1 , . . . , w_{ n - 1 } ) \sum_{ i = 1 }^{ n - 1 } w_i\)之和.

首先前面的\(\gcd\)可以使用\(\varphi * I = id\)来处理.于是剩下的问题在于我们如何将一个生成树的边的和代替乘积作为贡献来求和.

不妨进行扩域,令\(j^2 = 0 , j \ne 0\),这样我们可以类比复数来将每个数写作\(a + bj\)的模式.考虑将每条边的边权改为\(w_i j + 1\)并定义新域的四则运算,取最后得到的数\(a + bj\)\(b\)作为答案即可.

另外,注意到这样做复杂度\(wn^3\),很难通过.考虑每次只当边数大于等于\(n - 1\)的时候再跑行列式.不妨设\(\sigma ( n )\)\(n\)的因数个数,考虑如果因数很分散,那肯定复杂度很低,不然,我们有复杂度\(O ( n^3 \cfrac{ \sum_{ i = 1 }^m \sigma ( w_i ) }{ n - 1 } )\),可以通过.

Example([北京省选集训2019]生成树计数)

给定一个图,设第\(i\)条边的权值为\(w_i\),求所有生成树的\(( \sum_{ i = 1 }^{ n - 1 } w_i )^k\)之和.

考虑将第\(e\)条边边权改为\(\sum_{ i = 0 }^k \cfrac{ w_e^i x^i }{ i ! }\).根据多项式定理,显然最后取\([ x^k ]\)并乘以\(k !\)即可.

有向图情况

定义有向图的出度矩阵\(D^{ out } ( G ) = \begin{cases}0 & i \ne j \\ \deg^{ out }_i & i = j\end{cases}\),类似地可以定义入度矩阵\(D^{ in } ( G )\).

\(cnte ( i , j )\)为从\(i\)直接连向\(j\)的有向边个数,定义有向图的邻接矩阵\(A ( G )_{ i , j } = \begin{cases}0 & i = j \\ cnte ( i , j ) & i \ne j\end{cases}\)

定义有向图的出度基尔霍夫矩阵\(L^{ out } ( G ) = D^{ out } ( G ) - A ( G )\),同理可以定义其入度基尔霍夫矩阵\(L^{ in } ( G )\).

\(t^{ root } ( r , G )\)为图\(G\)\(r\)为根的根向生成树(\(r\)为根时,所有边都从儿子指向父亲)个数,同理可以定义叶向生成树个数\(t^{ leaf } ( r , G )\).

\(M^{ out }_{ r , r }\)\(L^{ out }\)的主余子式,有\(t^{ root } ( r , G ) = M^{ out }_{ r , r }\).叶向同理.

下面只简单提到根向生成树的证明,叶向同理.

类似于无向图,我们考虑构造\(n \times m\)矩阵\(A\)\(( n - 1 ) \times m\)矩阵\(B\):

\[ \begin{aligned} A_{ i , j } & = \begin{cases} 1 & e_j ' s \ head \ is \ i \\ - 1 & e_j ' s \ tail \ is \ i \\ 0 & other \end{cases} \\ B_{ i , j } & = \begin{cases} 1 & e_j ' s \ head \ is \ i \\ 0 & other \end{cases} \end{aligned} \]

剩下的部分与无向图类似.

BEST定理

\(ec ( G )\)为有向图\(G\)的欧拉回路个数,若其存在欧拉回路,则:

\[ ec ( G ) = t^{ root } ( G , x ) \prod_{ i = 1 }^n ( \deg_i - 1 ) ! \]

其中\(\deg_i = \deg^{ in }_i = \deg_i^{ out }\).

考虑如果勒令以\(x\)为起点,我们保留除了\(x\)以外每个点的最后经过的出边,最后一定会形成一棵根向树.而其他点可以随便选(由于我们勒令了每个点存在一个出边,所以不可能走到死胡同),这样的答案是\(t^{ root } ( G , x ) \deg_x \prod_{ i = 1 }^n ( \deg_i - 1 ) !\).

但是如果没有规定起点,考虑循环重构,在我们选择不同的边当作初始边时,只需循环一下总体的顺序,就可以得到以另一条边为初始边的另一个图,所以答案要比规定起点的答案多除一个\(\deg_x\).

格路计数问题

定义
  1. 在平面直角坐标系中,横坐标和纵坐标都是整数的点称为格点,平面格路是指从一个格点到另一格点只走格点的路,格路的长度是指其所走的路的步数.

  2. 对于一条从\(( 0 , 0 )\)\(( n , m )\)的格路,若其只使用了上步\(U = ( 0 , 1 )\),右步\(L = ( 1 , 0 )\),则我们称其为\(( n , m )\)自由路.

  3. \(\mathcal{ F } ( n , m )\)\(( n , m )\)自由路的集合,\(F ( n , m ) = \# \mathcal{ F } ( n , m )\)\(( n , m )\)自由路数量,即\(\mathcal{ F } ( n , m )\)的元素个数,显然\(F ( n , m ) = \binom{ n + m }{ n } \\\).

  4. 对于一条从\(( 0 , 0 )\)\(( n , m )\)的自由路,若其始终不经过对角线\(y = \cfrac{ m }{ n } x\)下方,则我们称之为\(( n , m ) - Dyck\)路.

  5. \(\mathcal{ D } ( n , m )\)\(( n , m )\)自由路的集合,\(D ( n , m ) = \# \mathcal{ D } ( n , m )\)\(( n , m )\)自由路数量,即\(\mathcal{ D } ( n , m )\)的元素个数.

  6. 对于从\(( 0 , 0 )\)\(( n , m )\)\(2\)条格路\(P , Q\),其中\(P = u_1 u_2 . . . u_{ n + m } , Q = v_1 v_2 . . . v_{ n + m } ( u_i , v_i \in{ L , U } , i = 1 , 2 , . . . , n + m )\).若 \(\exists i , u_{ i + 1 } . . . u_{ n + m } u_1 . . . u_i = v_1 v_2 . . . v_{ n + m }\),则我们称格路\(P , Q\)等价.将\(P\)的等价格路全集记为\([ P ]\).

  7. 对于任意格路\(P\),记\(P_k = u_{ k + 1 } . . . u_{ n + m } u_1 . . . u_k\),则\([ P ] = \{ P_k | k = 1 , 2 , 3 , · · · , n + m \}\).定义\(P\)的周期为使得\(P = P_k\)的最小数\(k\),用\(period ( P )\)表示,则显然有\(\# [ P ] = period ( P )\).

定理

散模型

多叉堆计数

有一棵树,要求给每个点一个\([ 1 , n ]\)的权值且不同的点权值不同,满足父亲的权值小于儿子的权值,求方案数.

不妨设以\(u\)为根节点的子树方案数为\(f_u\),\(u\)的儿子是\(v_1 , . . . , v_k\),注意到\(f_u = \binom{ siz_u - 1 }{ siz_{ v_1 } , siz_{ v_2 } , . . . , siz_{ v_k } } \prod f_{ v_i } = ( siz_u - 1 ) ! \prod_{ u \rightarrow v } \frac{ f_{ v } }{ siz_v ! } \\\).

那么考虑根的答案\(f_1\),考虑不断将\(f_1\)中含有的其它\(f_u\)向下展开,自然的,除了\(1\)号点外,每个点对答案都贡献了一个\(\frac{ 1 }{ siz }\),而根的贡献是\(( n - 1 ) !\).

也就是说,\(ans = ( n - 1 ) ! \prod_{ u = 2 }^n \frac{ 1 }{ siz_u } = n ! \prod_{ u = 1 }^n \frac{ 1 }{ siz_u } \\\).

Example1([AGC060C] Large Heap)

如果没有限制,就是一个简单的多叉堆计数.

而有了限制怎么做呢?我们考虑把\(u\)\(1\)的路径和\(v\)\(1\)的路径归并起来,会得到一条长链.我们只要确定了长链上的元素,通过组合数以及二叉堆计数,自然可以算出不在长链上的元素的答案.而对于长链上的元素,我们可以直接设计一个\(O ( n^2 )\)的dp即可.

Example2([HEOI2013]SAO)

显然给出的是一张树形图,然后每条边有一个限制表示这条边所连接的两个点哪个更大.现在给每个点一个\([ 1 , n ]\)的权值且不同的点权值不同求方案数.

我们随便找一个点然后当成有根树做,然后如果只有父亲小于儿子的边就是简单的多叉堆计数.不然,我们可以做一个简单容斥.这样问题就又转化回多叉堆计数,容斥部分写一个树形dp就好.

补一下,这个树形dp没有那么简单.首先你注意到多叉堆计数是跟子树大小有关系的,所以你不能简单地设计\(f_{ i , j }\)表示\(i\)子树内选中了\(j\)条边的代价,你必须加一维来处理子树大小,也就是设\(f_{ u , siz , cnt }\)表示\(u\)所在连通块大小为\(siz\),子树中总共选择了\(cnt\)条边的代价.

但是注意到这题的容斥系数是\(( - 1 )^k\),其中\(k\)是选择的儿子小于父亲的数量,然后其它的要求儿子大于父亲的边随便选.你发现你选中了一条边,无非是对答案乘以一个\(- 1\),这是没有必要记录的.因此直接以\(f_{ u , siz }\)的状态转移就行.

这个故事告诉我们别什么容斥都最后算,你能在做的过程中把\(- 1\)乘上去就别惦记最后统一求和了.

三元环计数

我们对原图建立一个新的有向图,在新图中,如果\(u \rightarrow v\),则在原图中\(\deg u < \deg v\)\(\deg u = \deg v \land u < v\).根据自然根号,每个点的出度不会超过\(O ( \sqrt{ n } )\).

接下来枚举原图的一条边\(u \leftrightarrow v\),只要在新的图中找到\(w\)满足\(u \rightarrow v , u \rightarrow w , v \rightarrow w\)即可.打tag做一做,复杂度\(O ( n \sqrt{ n } )\).

四元环计数

仍然类似三元环计数那样建立新图.

考虑原图中的两条边\(u \leftrightarrow v\)\(u \leftrightarrow v '\),我们考虑对四元环中度数最大的那个点\(w\)计数,对于这个\(w\)统计一个tag表示形如\(u \leftrightarrow v \rightarrow w\)的数量,每次改变\(u\)的时候清空一下全图tag.

有标号DAG计数

即:

$$ \[\begin{aligned} f_n & = \sum_{ k = 1 }^n \binom{ n }{ k } ( - 1 )^{ k - 1 } 2^{ k ( n - k ) } f_{ n - k } \\ \end{aligned}\]

$$

证明见反演与容斥-子集反演-Example2.

Example1(qoj5749)

注意到一个环内部不能有任何边,那么其实也就是有标号DAG计数,只不过要乘上一个斯特林数.不妨设\(g_{ n , m }\)\(n\)个点\(m\)条边的答案,再设\(G_n\)为其生成函数.事实上,我们自然有:

$$ \[\begin{aligned} G_n & = \sum_{ k = 1 } \binom{ n }{ k } \sum_{ j = 1 }^k{ k \brack j } ( - 1 )^{ j - 1 } ( 1 + z )^{ k ( n - k ) } G_{ n - k } \\ & = \sum_{ k = 1 } \binom{ n }{ k } ( 1 + z )^{ k ( n - k ) } G_{ n - k } \sum_{ j = 1 }^k{ k \brack j } ( - 1 )^{ j - 1 } \\ \end{aligned}\]

$$

逆用斯特林公式,如果\(n \geq 1\):

\[ \sum_{ i }{ n \brack i } ( - 1 )^{ i - 1 } = ( - 1 ) \times ( - 1 )^{ \overline{ n } } = [ n = 1 ] \]

注意到\(G_1 = 1\),于是:

\[ \begin{aligned} G_n & = n ( 1 + z )^{ n - 1 } G_{ n - 1 } \\ & = n ! ( 1 + z )^{ \frac{ n ( n - 1 ) }{ 2 } } \\ [ z^m ] G_n & = n ! \binom{ \frac{ n ( n - 1 ) }{ 2 } }{ m } \end{aligned} \]

反演

假设有两个函数\(f\)\(g\)满足:\(f ( n ) = \sum_{ k } a_{ n , k } g ( k )\),已知f求g的过程称为反演.

一般情况下,求反演只能高斯消元,但是有一些形式的反演有巧妙解法.

子集反演

一般形式:

\[ \begin{aligned} f ( S ) & = \sum_{ T \subseteq S } g ( T ) \Leftrightarrow g ( S ) = \sum_{ T \subseteq S } ( - 1 )^{ | S | - | T | } f ( T ) \\ f ( S ) & = \sum_{ S \subseteq T \subseteq U } g ( T ) \Leftrightarrow g ( S ) = \sum_{ S \subseteq T \subseteq U } ( - 1 )^{ | T | - | S | } f ( T ) \end{aligned} \]

证明:

\[ \begin{aligned} g ( S ) & = \sum_{ T \subseteq S } ( - 1 )^{ | S | - | T | } f ( T ) \\ & = ( - 1 )^{ | S | } \sum_{ T \subseteq S } ( - 1 )^{ | T | } \sum_{ P \subseteq T } g ( P ) \\ & = ( - 1 )^{ | S | } \sum_{ P \subseteq S } g ( P ) \sum_{ T \subseteq S / P } ( - 1 )^{ | T | + | P | } \\ & = ( - 1 )^{ | S | } \sum_{ P \subseteq S } g ( P ) ( - 1 )^{ | P | } \sum_{ T \subseteq S / P } ( - 1 )^{ | T | } \\ & = ( - 1 )^{ | S | } \sum_{ P \subseteq S } g ( P ) [ S = P ] ( - 1 )^{ | P | } \\ & = g ( S ) \end{aligned} \]

不难发现,这个子集反演也就相当于在做高维前后缀和.

Example1(2019zrpzt七连day1D)

根据子集反演,设\(cnt_S\)为集合为\(S\)的数量,然后设\(f_S = \sum_{ S ' \subseteq S } cnt_{ S ' }\),有:\(ans = \sum_{ S } 2^{ f_S } ( - 1 )^{ n - | S | }\).

做一遍高维前缀和就好,复杂度\(O ( n 2^n )\),应该也可以用分治FMT无脑做到\(O ( n^2 2^n )\).

Example2(有标号DAG计数)

\(f_{ i , j }\)表示\(i\)个点,其中有\(j\)个点的入度数为\(0\)的方案数.(等一下,为撒子想到要记度数为\(0\)的点咧?因为你要一层一层转移,而在DAG中一层一层的就是零度点.而且说到底,你注意到有编号这个事实其实是很烦的,因为考虑如果一个一个点放上去,就有可能出现放的地方是等价的.而这么一层一层是绝对不会出现等价点的问题的.再说的仔细一点,如果我们把位置空着,然后选出一些放上来,是会出现等价点的问题的.但如果我们先选出来,然后再把边连上就不会.于是我们必须要枚举一些点然后再连到上面去)

这样我们每次枚举删去这\(j\)个点后,还剩下\(k\)个零度点.于是自然有:

\[ f_{ i , j } = \binom{ i }{ j } \sum_{ k = 1 }^{ i - j } ( 2^j - 1 )^k 2^{ j ( i - j - k ) } f_{ i - j , k } \]

等一下咧,这复杂度\(O ( n^3 )\)了,这咋办啊?

好像转移优化不太了,因为\(k\)很难省去(在指数上).但我们注意到我们定义的时候说:\(0\)度点的数量恰好为\(k\),这个条件好像太强了果然OI就是发现限制太强了就弱一点,发现太弱了就强一点,所以我们想办法把它放弱一点.

一个经典的方法是:我们把定义改为至少\(k\)个零度点.但是这样转移好像还是不太行:零度点的情况太多了.那我们不妨考虑容斥,因为推导容斥的过程中,永远不害怕情况太多:我们直接考虑所有情况的集合.当然能不能推到最后是另一回事.

我们设\(f ( n , S )\)表示\(n\)个点,其中只有\(S\)中的点的入度为\(0\);类似定义\(g ( n , S )\)表示\(n\)个点,至少\(S\)中的点的入度为\(0\).显然我们所求也就是\(g ( n , \emptyset )\),注意到:

\[ \begin{aligned} g ( n , S ) & = 2^{ | S | ( n - | S | ) } g ( n - | S | , \emptyset ) \\ g ( n , S ) & = \sum_{ S \subseteq T } f ( n , T ) \end{aligned} \]

对第二个式子用子集反演,有:

\[ f ( n , S ) = \sum_{ S \subseteq T } ( - 1 )^{ | T | - | S | } g ( n , T ) \]

接下来使用反复带入大法:

$$ \[\begin{aligned} g ( n , \emptyset ) & = \sum_{ \emptyset \ne T } f ( n , T ) \\ & = \sum_{ T \subseteq S } ( - 1 )^{ | S | - | T | } g ( n , S ) \\ & = \sum_{ T \subseteq S } ( - 1 )^{ | S | - | T | } 2^{ | S | ( n - | S | ) } g ( n - | S | , \emptyset ) \\ & = \sum_{ m = 1 }^n \sum_{ | T | = m } \sum_{ T \subseteq S } ( - 1 )^{ | S | - | T | } 2^{ | S | ( n - | S | ) } g ( n - | S | , \emptyset ) \\ & = \sum_{ m = 1 }^n \binom{ n }{ m } \sum_{ k = m }^n \binom{ n - m }{ k - m } ( - 1 )^{ k - m } 2^{ k ( n - k ) } g ( n - k , \emptyset ) \\ \end{aligned}\]

$$

可以发现:我们在推式子的过程中,将和集合本身有关的性质转化为了只和集合大小有关的式子,于是就简化了大量运算.

接下来我们继续化简:

$$ \[\begin{aligned} & \sum_{ m = 1 }^n \binom{ n }{ m } \sum_{ k = m }^n \binom{ n - m }{ k - m } ( - 1 )^{ k - m } 2^{ k ( n - k ) } g ( n - k , \emptyset ) \\ = & \sum_{ k = 1 }^n \sum_{ m = 1 }^k \binom{ n }{ m } \binom{ n - m }{ k - m } ( - 1 )^{ k - m } 2^{ k ( n - k ) } g ( n - k , \emptyset ) \\ = & \sum_{ k = 1 }^n \binom{ n }{ k } 2^{ k ( n - k ) } g ( n - k , \emptyset ) \sum_{ m = 1 }^k \binom{ k }{ m } ( - 1 )^{ k - m } \\ = & \sum_{ k = 1 }^n \binom{ n }{ k } 2^{ k ( n - k ) } g ( n - k , \emptyset ) ( ( 1 - 1 )^k - ( - 1 )^k ) \\ = & \sum_{ k = 1 }^n \binom{ n }{ k } 2^{ k ( n - k ) } g ( n - k , \emptyset ) ( - 1 )^{ k - 1 } \\ \end{aligned}\]

$$

注意到复杂度已经降到\(O ( n^2 )\)了.

上面是从集合的角度一步步分析得到的.但如果你直接从容斥的角度考虑,忽略掉那个\(( - 1 )^{ k - 1 }\),把它当成一个可以数学归纳出来的容斥系数,那么这个式子会得到一个很简单的理解方式:

$$ \[\begin{aligned} f_n & = \sum_{ k = 1 }^n \binom{ n }{ k } ( - 1 )^{ k - 1 } 2^{ k ( n - k ) } f_{ n - k } \\ \end{aligned}\]

$$

也就是直接设,然后钦定其有至少\(j\)个,然后配容斥系数.

二项式反演

一般形式:

$$ \[\begin{aligned} f ( n ) & = \sum_{ k = 0 }^n C_n^k g ( k ) \Leftrightarrow g ( n ) = \sum_{ k = 0 }^n ( - 1 )^{ n - k } C_n^k f ( k ) \\ f ( n ) & = \sum_{ k = 0 }^n ( - 1 )^k \binom{ n }{ k } g ( k ) \Leftrightarrow g ( n ) = \sum_{ k = 0 }^n ( - 1 )^k \binom{ n }{ k } f ( k ) \\ f ( n ) & = \sum_{ k = n }^N C_k^n g ( k ) \Leftrightarrow g ( n ) = \sum_{ k = n }^N ( - 1 )^{ k - n } C_k^n f ( k ) \\ f ( n ) & = \sum_{ k = n }^N ( - 1 )^k \binom{ k }{ n } g ( k ) \Leftrightarrow g ( n ) = \sum_{ k = n }^N ( - 1 )^k \binom{ k }{ n } f ( k ) \\ \end{aligned}\]

$$

显然以\(( - 1 )^n g ( n )\)代替\(g ( n )\)即可从第一个式子推导第二个式子,下面证明第一个式子:

$$ \[\begin{aligned} g ( n ) & = \sum_{ k = 0 }^n ( - 1 )^{ n - k } C_n^k f ( k ) \\ & = \sum_{ m = 0 }^n \sum_{ k = 0 }^{ n - m } ( - 1 )^k C_{ n - m }^k C_n^m g ( m ) \\ & = \sum_{ k = 0 }^n ( - 1 )^k C_n^k \sum_{ m = 0 }^{ n - k } C_{ n - k }^m g ( m ) \\ & = \sum_{ k = 0 }^n ( - 1 )^k C_n^k f ( n - k ) \\ & = \sum_{ k = 0 }^n ( - 1 )^{ n - k } C_n^k f ( k ) \\ \end{aligned}\]

$$

Example1(错排问题)

\(n\)个有编号的人站成一排,求他们都没有站到自己编号对应位置的方案数.

\(f ( n )\)\(n\)个人随便站的方案数,\(g ( n )\)\(n\)个人都站错的方案数.

如果知道\(g\)的表达式,我们可以通过枚举有多少人站错位置来得到\(f\),即:\(f ( n ) = \sum_{ k = 0 }^n C_n^k g ( k )\).

显然就是一个二项式反演,\(g ( n ) = \sum_{ k = 0 }^n ( - 1 )^{ n - k } C_n^k f ( k ) = \sum_{ k = 0 }^n ( - 1 )^{ n - k } C_n^k k !\).

值得一提的是,我们再观察一下最后得到的错排公式并进行一定的化简,可以得到:\(g ( n ) = n ! \sum_{ 0 \leq k \leq n } \cfrac{ ( - 1 )^k }{ k ! } \\\).

不难发现\(n !\)的后面形如\(e^{ - 1 }\)的泰勒展开,我们考虑直接将泰勒展开的公式带入,可以得到:

\[ \begin{aligned} g ( n ) & = \cfrac{ n ! }{ e } - n ! \sum_{ k > n } \cfrac{ ( - 1 )^k }{ k ! } \\ & = \cfrac{ n ! }{ e } - \cfrac{ ( - 1 )^{ n + 1 } }{ n + 1 } \sum_{ 0 \leq k } ( - 1 )^k \cfrac{ ( n + 1 ) ! }{ ( k + n + 1 ) ! } \end{aligned} \]

用一些我不会的方法分析误差,会发现后面的项所能带来的误差很小,于是有\(g ( n ) = \lfloor \cfrac{ n ! }{ e } + \cfrac{ 1 }{ 2 } \rfloor + [ n = 0 ]\).

另外,观察\(g\)关于\(f\)的表达式,不难求出\(g\)的递推式:\(g ( n ) = ng ( n - 1 ) + ( - 1 )^n\).

下面证明\(g_n = ( n - 1 ) ( g_{ n - 1 } + g_{ n - 2 } )\),事实上,右边等于:

$$ \[\begin{aligned} & ( n - 1 ) ( g_{ n - 1 } + g_{ n - 2 } ) \\ = & ( - 1 )^{ n - 1 } ( n - 1 ) + ( n - 1 ) \sum_{ k = 0 }^{ n - 2 } ( ( n - 1 ) ! \frac{ ( - 1 )^k }{ k ! } + ( n - 2 ) ! \frac{ ( - 1 )^k }{ k ! } ) \\ = & n ! \sum_{ k = 0 }^{ n - 2 } \frac{ ( - 1 )^k }{ k ! } - ( n - 1 ) ( - 1 )^n \\ \end{aligned}\]

$$

Example2(CF1750G)

如果没有字典序限制就是经典的二项式反演:考虑能被分为\(k\)段,说明有\(n - k\)个位置和前一个位置是大一的关系.我们钦定这些位置即可.

而有字典序限制也很经典,枚举LCP,枚举下一个位置,这个时候值域被分为若干个区间,假设剩了\(x\)个数字,\(y\)个区间,那么钦定\(j\)对的方案是\(\binom{ x - y }{ j } ( x - j ) !\).然后要乘上前面已经有了的,也就是乘上形如\(( 1 + z )^k\).这样复杂度\(O ( n^4 )\).

这种问题通常LCP后的下一个位置都可以规避,这里你发现不同的取值只会让后面的\(x , y , k\)\(O ( 1 )\)种不同的取值,因此不用枚举.这样就是\(O ( n^3 )\).但是那个多项式乘法也可以规避,考虑最后的答案形如\(\sum ( 1 + z )^k P_k ( x )\),我们考虑写成\(P_{ n - 1 } ( z ) + = ( 1 + z ) P_n ( z )\),然后不断这么做,就只需要\(O ( n^2 )\).

Example3(CF1228E)

不妨设至多有\(i\)\(j\)列最小值为\(1\)的答案是\(f_{ i , j }\),恰好有\(i\)\(j\)列最小值为\(1\)的答案是\(g_{ i , j }\),注意到:

\[ f_{ n , m } = \sum_{ i = 0 }^n \binom{ n }{ i } \sum_{ j = 0 }^m \binom{ m }{ j } g_{ i , j } \]

\(h_{ n , m } = \sum_{ j = 0 }^m \binom{ m }{ j } g_{ n , j } \\\),则\(f_{ n , m } = \sum_{ i = 0 }^n \binom{ n }{ i } h_{ i , m } \\\),而\(f_{ n , m } = k^{ nm } ( k - 1 )^{ NM - nm }\).做两次二项式反演得到\(g\).

写到这里发现一个问题(其实是我发现问题后把上面原本写错的给改了),为啥\(f_{ n , m } \ne \binom{ N }{ n } \binom{ M }{ m } k^{ nm } ( k - 1 )^{ NM - nm }\)呢?我们写成子集反演形式看看:

$$ \[\begin{aligned} f_{ S , T } & = \sum_{ s \subseteq S } \sum_{ t \subseteq T } g_{ s , t } \\ f_{ S , T } & = \sum_{ s \subseteq S } h_{ s , T } \\ h_{ S , T } & = \sum_{ t \subseteq T } g_{ S , t } \\ \end{aligned}\]

$$

做子集反演:

\[ \begin{aligned} f_{ S , T } & = k^{ | S | \times | T | } ( k - 1 )^{ NM - | S | | T | } \\ h_{ s , T } & = \sum_{ S \subseteq s } ( - 1 )^{ | s | - | S | } f_{ S , T } \\ g_{ s , t } & = \sum_{ T \subseteq t } ( - 1 )^{ | t | - | T | } h_{ s , T } \end{aligned} \]

把集合改成集合大小就可以发现问题所在:

换句话说,\(g_{ n , m }\)本身就包含了所有\(| S | = n , | T | = m\)的情况的和,并且在组合数\(\binom{ m }{ j }\)那里就找到了唯一确定的\(f_{ s , t }\),因此\(f_{ n , m }\)是唯一确定的.这意味着这里\(f\)\(n , m\)并非集合之和,而是已经确定的集合的大小.

啥?这和我平常接触的二项式反演不一样啊?不说别的,第四题(BZOJ2839)的式子是这样的:

\[ \begin{aligned} f_i & = 2^{ 2^{ n - i } } \binom{ n }{ i } \\ f_k & = \sum_{ i = k }^n \binom{ i }{ k } g_i \\ g_k & = \sum_{ i = k }^n ( - 1 )^{ i - k } \binom{ i }{ k } f_i \end{aligned} \]

冷静一下,二项式反演的公式肯定没错,那也就一定是下面这几句出现了问题:

\[ f_{ n , m } = \sum_{ i = 0 }^n \binom{ n }{ i } \sum_{ j = 0 }^m \binom{ m }{ j } g_{ i , j } \]

这个问题其实非常显然,我们的\(g_{ i , j }\)定义为所有\(| S | = i , | T | = j\)的答案之和.\(f\)也是这么定义的,那这个式子就是错的,应该写成:

\[ f_{ n , m } = \sum_{ i = 0 }^n \binom{ N - i }{ n - i } \sum_{ j = 0 }^m \binom{ M - j }{ m - j } g_{ i , j } \]

这样才是在不确定的那些行列中选择组合数,而不是在确定的那些行列中选.

但这样又有一个问题,就是这个题的特殊性,这个题要求\(g_{ N , M }\),那此时\(g\)怎么定义不应该是一样的吗?

当然不一样,二项式反演讲究统一性,所有的定义必须遵循一个统一的原则,不然如果什么样子的函数都能反演,那一般的反演就不是一个需要解方程才能完成的东西了.

回到第四题,再看一遍这个式子:

$$ \[\begin{aligned} f_k & = \sum_{ i = k }^n \binom{ i }{ k } g_i \\ \end{aligned}\]

$$

这个定义式就非常良性,\(g\)是已知的集合,\(f\)是未知的集合.我们乘上组合数就可以得到对于\(f\)来说已知的集合.因此这个就非常正确.

回到这个题上,为什么我们最后把\(f\)的定义改成\(f_{ n , m } = k^{ nm } ( k - 1 )^{ NM - nm }\)就对了呢?

再看看这个式子:

\[ f_{ n , m } = \sum_{ i = 0 }^n \binom{ n }{ i } \sum_{ j = 0 }^m \binom{ m }{ j } g_{ i , j } \]

这个式子的右边在干这样一件事:那就是在已知\(n\)\(m\)列的集合的前提下,从中选出\(i\)\(j\)列并求\(g\).那么你从哪知道的\(n\)\(m\)列呢?你得组合数啊!

所以,实际上的\(f\)是这样的:

\[ \begin{aligned} f_{ n , m } & = \binom{ N }{ n } \binom{ M }{ m } \sum_{ i = 0 }^n \binom{ n }{ i } \sum_{ j = 0 }^m \binom{ m }{ j } g_{ i , j } \\ f_{ n , m } & = \binom{ N }{ n } \binom{ M }{ m } k^{ nm } ( k - 1 )^{ NM - nm } \end{aligned} \]

好麻烦啊,能不能避免这种需要进一步思考集合意义的问题呢?

考虑二项式反演的第二个形式:

$$ \[\begin{aligned} f ( n ) & = \sum_{ k = n }^N C_n^k g ( k ) \Leftrightarrow g ( n ) = \sum_{ k = n }^N ( - 1 )^{ k - n } C_n^k f ( k ) \\ \end{aligned}\]

$$

不难发现这个式子无论怎么写,前后都一定是从已知集合中选东西.绝对不会出现上面的问题.

因此,我们重新写一下这个题的相关式子,考虑直接正难则反,设\(f '_{ i , j }\)为至少有\(i\)\(j\)列不满足条件的方案数,自然有\(f '_{ i , j } = f_{ N - i , M - j }\).你发现此时一定有:

\[ f '_{ n , m } = \sum_{ i = n }^N \binom{ i }{ n } \sum_{ j = m }^M \binom{ j }{ m } g '_{ i , j } \]

最后答案就是\(g '_{ 0 , 0 }\).

斯特林反演

一般形式:

$$ \[\begin{aligned} f ( n ) & = \sum_{ k = 0 }^n \left \{ \begin{array} { c } n \\ k \end{array} \right \} g ( k ) \Leftrightarrow g ( n ) = \sum_{ k = 0 }^n \left [ \begin{array} { c } n \\ k \end{array} \right ] ( - 1 )^{ n - k } f ( k ) \\ f ( n ) & = \sum_{ k = 0 }^n \left [ \begin{array} { c } n \\ k \end{array} \right ] g ( k ) \Leftrightarrow g ( n ) = \sum_{ k = 0 }^n \left \{ \begin{array} { c } n \\ k \end{array} \right \} ( - 1 )^{ n - k } f ( k ) \\ f ( m ) & = \sum_{ n = m }^M ( - 1 )^{ m - n } \left [ \begin{array} { c } n \\ m \end{array} \right ] g ( n ) \Leftrightarrow g ( m ) = \sum_{ k = 0 }^M \left \{ \begin{array} { c } k \\ m \end{array} \right \} f ( k ) \\ f ( m ) & = \sum_{ n = m }^M ( - 1 )^{ m - n } \left \{ \begin{array} { c } n \\ m \end{array} \right \} g ( n ) \Leftrightarrow g ( m ) = \sum_{ k = 0 }^M \left [ \begin{array} { c } k \\ m \end{array} \right ] f ( k ) \\ \end{aligned}\]

$$

考虑第一类斯特林数和第二类斯特林数的对称性,只需证明第一个和第三个式子即可.

反转公式:

$$ \[\begin{aligned} \sum_{ k = 0 }^n \left [ \begin{array} { c } n \\ k \end{array} \right ] \left \{ \begin{array} { c } k \\ m \end{array} \right \} ( - 1 )^{ n - k } & = \sum_{ k = 0 }^n \left \{ \begin{array} { c } n \\ k \end{array} \right \} \left [ \begin{array} { c } k \\ m \end{array} \right ] ( - 1 )^{ n - k } = [ m = n ] \\ \end{aligned}\]

$$

第一个式子的证明:

$$ \[\begin{aligned} g ( n ) & = \sum_{ m = 0 }^n [ m = n ] g ( m ) \\ & = \sum_{ m = 0 }^n \sum_{ k = 0 }^n \left [ \begin{array} { c } n \\ k \end{array} \right ] \left \{ \begin{array} { c } k \\ m \end{array} \right \} ( - 1 )^{ n - k } g ( m ) \\ & = \sum_{ k = 0 }^n \left [ \begin{array} { c } n \\ k \end{array} \right ] ( - 1 )^{ n - k } \sum_{ m = 0 }^k \left \{ \begin{array} { c } k \\ m \end{array} \right \} g ( m ) = \sum_{ k = 0 }^n \left [ \begin{array} { c } n \\ k \end{array} \right ] ( - 1 )^{ n - k } f ( k ) \\ \end{aligned}\]

$$

第三个式子的证明:

$$ \[\begin{aligned} g ( m ) & = \sum_{ n = m }^M [ n = m ] g ( n ) \\ & = \sum_{ n = m }^M \sum_{ k = 0 }^M \left [ \begin{array} { c } n \\ k \end{array} \right ] \left \{ \begin{array} { c } k \\ m \end{array} \right \} ( - 1 )^{ n - k } g ( n ) \\ & = \sum_{ k = 0 }^M \left \{ \begin{array} { c } k \\ m \end{array} \right \} f ( k ) \\ \end{aligned}\]

$$

莫比乌斯反演

一般形式:

\[ \begin{aligned} f ( n ) & = \sum_{ d | n } g ( d ) \Leftrightarrow g ( n ) = \sum_{ d | n } \mu ( \frac{ n }{ d } ) f ( d ) \\ f ( n ) & = \sum_{ n | d } g ( d ) \Leftrightarrow g ( n ) = \sum_{ n | d } \mu ( \frac{ d }{ n } ) f ( d ) \\ f ( x ) & = \sum_{ 1 \leq d } g ( d ) \Leftrightarrow g ( x ) = \sum_{ 1 \leq d } f ( \cfrac{ x }{ d } ) \mu ( d ) \end{aligned} \]

第一个式子的证明:

$$ \[\begin{aligned} g ( n ) & = \sum_{ m | n } [ \frac{ n }{ m } = 1 ] g ( m ) \\ & = \sum_{ m | n } \sum_{ d | \frac{ n }{ m } } \mu ( d ) g ( m ) \\ \end{aligned}\]

$$

注意到\([ d | \frac{ n }{ m } ] = [ md | n ] = [ m | \frac{ n }{ d } ] \\\).

$$ \[\begin{aligned} g ( n ) & = \sum_{ d | n } \mu ( d ) \sum_{ m | \frac{ n }{ d } } g ( m ) \\ & = \sum_{ d | n } \mu ( d ) f ( \frac{ n }{ d } ) \\ & = \sum_{ d | n } \mu ( \frac{ n }{ d } ) f ( d ) \\ \end{aligned}\]

$$

第二个式子的证明:

$$ \[\begin{aligned} g ( n ) & = \sum_{ n | d } [ \frac{ d }{ n } = 1 ] g ( d ) \\ & = \sum_{ n | d } \sum_{ c | \frac{ d }{ n } } \mu ( c ) g ( d ) \\ & = \sum_{ c | d } \sum_{ nc | d } \mu ( c ) g ( d ) \\ & = \sum_{ c } \mu ( c ) f ( nc ) \\ & = \sum_{ n | d } \mu ( \frac{ d }{ n } ) f ( d ) \\ \end{aligned}\]

$$

第三个式子的证明:

\[ \begin{aligned} \sum_{ 1 \leq d } g ( \cfrac{ x }{ d } ) \mu ( d ) & = \sum_{ d \geq 1 } \mu ( d ) \sum_{ k \geq 1 } f ( \cfrac{ x }{ kd } ) \\ & = \sum_{ m \geq 1 } f ( \cfrac{ x }{ m } ) \sum_{ d , k \geq 1 } [ m = dk ] \mu ( d ) \\ & = \sum_{ m \geq 1 } f ( \cfrac{ x }{ m } ) \sum_{ d | m } \mu ( d ) \\ & = f ( x ) \end{aligned} \]

Example1

求长度为\(n\)且仅包含小写英文字母且循环节长度恰为\(n\)的字符串个数.

不妨设\(f ( n )\)表示长度为\(n\)的字符串个数,\(g ( n )\)表示长度为\(n\)且循环节长度恰为\(n\)的字符串个数.

\(f ( n ) = \sum_{ d | n } g ( d )\),根据莫比乌斯反演,\(g ( n ) = \sum_{ d | n } \mu ( \cfrac{ n }{ d } ) f ( d )\).

Example2

\(\sum_{ i = 1 }^{ n } \sum_{ j = 1 }^m gcd ( i , j ) \\\).

我们通过这个题来讲一下推导技巧.

增加枚举量
$$ \[\begin{aligned} \sum_{ i = 1 }^{ n } \sum_{ j = 1 }^m gcd ( i , j ) & = \sum_{ i = 1 }^n \sum_{ j = 1 }^m id [ gcd ( i , j ) ] \\ & = \sum_{ i = 1 }^n \sum_{ j = 1 }^m \sum_{ d | gcd ( i , j ) } \varphi ( d ) \\ \end{aligned}\]

$$

交换枚举顺序
$$ \[\begin{aligned} \sum_{ i = 1 }^n \sum_{ j = 1 }^m \sum_{ d | gcd ( i , j ) } \varphi ( d ) & = \sum_{ d = 1 }^{ \min ( n , m ) } \sum^{ \lfloor \frac{ n }{ d } \rfloor }_{ i = 1 } \sum^{ \lfloor \frac{ m }{ d } \rfloor }_{ j = 1 } \varphi ( d ) \\ \end{aligned}\]

$$

分离无关变量
$$ \[\begin{aligned} \sum_{ d = 1 }^{ \min ( n , m ) } \sum^{ \lfloor \frac{ n }{ d } \rfloor }_{ i = 1 } \sum^{ \lfloor \frac{ m }{ d } \rfloor }_{ j = 1 } \varphi ( d ) & = \sum^{ \min ( n , m ) }_{ d = 1 } \varphi ( d ) \times \lfloor \cfrac{ n }{ d } \rfloor \times \lfloor \cfrac{ m }{ d } \rfloor \\ \end{aligned}\]

$$

考虑使用数论分块,只需处理出\(\varphi ( d )\)的前缀和即可在\(O ( \sqrt{ n } + \sqrt{ m } )\)的复杂度解决此问题.

Example3

\(\sum_{ i = 1 }^{ n } \sum_{ j = 1 }^m [ gcd ( i , j ) = 1 ] \\\).

和上一道题几乎没区别,唯一不同的是需要处理的函数从\(id\)变为了\(\epsilon\).

Example4

\(\sum_{ i = 1 }^{ n } \sum_{ j = 1 }^m [ gcd ( i , j ) \in \mathrm{ prime } ] \\\).

考虑增加枚举量,则:

$$ \[\begin{aligned} \sum_{ i = 1 }^{ n } \sum_{ j = 1 }^m [ gcd ( i , j ) & \in \mathrm{ prime } ] = \sum_{ i = 1 }^{ n } \sum_{ j = 1 }^m \sum_{ p \in \mathrm{ prime } } [ gcd ( i , j ) = p ] \\ & = \sum_{ p \in \mathrm{ prime } } \sum^{ \lfloor \frac{ n }{ d } \rfloor }_{ i = 1 } \sum^{ \lfloor \frac{ m }{ d } \rfloor }_{ j = 1 } [ gcd ( pi , pj ) = p ] \\ & = \sum_{ p \in \mathrm{ prime } } \sum^{ \lfloor \frac{ n }{ p } \rfloor }_{ i = 1 } \sum^{ \lfloor \frac{ m }{ p } \rfloor }_{ j = 1 } [ gcd ( i , j ) = 1 ] \\ & = \sum_{ p \in \mathrm{ prime } } \sum_{ d = 1 }^{ \min ( \lfloor \frac{ m }{ p } \rfloor , \lfloor \frac{ n }{ p } \rfloor ) } \mu ( d ) \lfloor \cfrac{ n }{ pd } \rfloor \lfloor \cfrac{ m }{ pd } \rfloor \\ \end{aligned}\]

$$

于是转化为上一道题,但复杂度仍不可接受.

换元

考虑设\(x = pd\),则变为\(\sum_{ x = 1 }^{ \min ( n , m ) } \sum_{ p \in \mathrm{ prime } \land p | x } \mu ( \frac{ x }{ p } ) \lfloor \frac{ n }{ x } \rfloor \lfloor \frac{ m }{ x } \rfloor \\\).

Example5([UR #5]怎样跑得更快)

首先先考虑去掉\(lcm\)使得式子中只有\(i , j , \gcd ( i , j )\).

显然可以构造函数\(f ( x ) = x^{ c - d } , g ( x ) = x^d , h ( x ) = x^d \\\),然后将题目转化为\(\sum_{ j = 1 }^n f ( gcd ( i , j ) ) g ( i ) h ( j ) x_j \equiv b_i ( \mod p ) \\\).

\(\gcd ( i , j )\)很难处理,于是考虑用莫比乌斯反演消掉.

可以求出\(f_r ( n )\)使得\(f ( n ) = \sum_{ d | n } f_r ( d ) \\\),也即\(f_r ( n ) = \sum_{ d | n } \mu ( \cfrac{ n }{ d } ) f ( d )\).

则原式即:

$$ \[\begin{aligned} \sum_{ j = 1 }^n \sum_{ d } [ d | i ] [ d | j ] f_r ( d ) g ( i ) h ( j ) x_j & \equiv b_i ( \mod p ) \\ \sum_{ d | i } f_r ( d ) \sum_{ j = 1 }^n [ d | j ] h ( j ) x_j & \equiv \frac{ b_i }{ g ( i ) } ( \mod p ) \\ \end{aligned}\]

$$

\(z_d = \sum_{ j = 1 }^n [ d | j ] h ( j ) x_j \\\),有\(\sum_{ d | i } f_r ( d ) z_d \equiv \frac{ b_i }{ g ( i ) } ( \mod p ) \\\).

这个也是一个莫比乌斯反演的形式,我们可以求出左边,进而求出\(z_d\).

\(z_d = \sum_{ j = 1 }^n [ d | j ] h ( j ) x_j = \sum_{ d | j }^n h ( j ) x_j\),可以再次使用莫比乌斯反演求出\(h ( j ) x_j\),进而求\(x_j\).

无解条件显然是\(g_i = 0 \land x_i \ne 0\).

简而言之,这个题的步骤就是:

  1. 通过增加枚举量消掉\(lcm\)以及\(\gcd\)这些难以处理的项.

  2. \(i\)\(j\)尽量分到式子两边.

  3. 先通过莫比乌斯反演求出一些值,再通过这些值反推.

Example6([CF1566H]Xor-quiz)

首先注意到一个重要的事实:我们只需要询问所有\(\mu ( x ) \ne 0\)\(x\),就可以得到全部信息,而这些\(x\)的数量是完全足够我们全部询问一遍的.

注意到一个事实是,异或是模意义下的按位加减法,这意味着我们可以对异或做莫比乌斯反演.事实上,我们有:

$$ \[\begin{aligned} f ( n ) & = \bigoplus_{ i \in A } i [ \gcd ( i , n ) = 1 ] \\ & = \bigoplus_{ i \in A }^c i \sum_{ d | i , d | n } \mu ( d ) \\ \end{aligned}\]

$$

注意到\(\sum_{ d | i } \mu ( d ) = \bigoplus_{ d | i } | \mu ( d ) |\),于是:

\[ f ( n ) = \bigoplus_{ d | n } | \mu ( d ) | \bigoplus_{ d | i , i \in A } i \]

接下来只要我们形式上写作\(n\),我们就默认\(\mu ( n ) \ne 0\),又令\(g ( n ) = \bigoplus_{ n | i , i \in A } i\),此时自然有\(f ( n ) = \bigoplus_{ d | n } g ( d ) \\\).这是一个经典的莫反形式,我们再反演回去就可以得到\(g ( n ) = \bigoplus_{ d | n } \mu ( \frac{ n }{ d } ) f ( d ) = \bigoplus_{ d | n } f ( d )\),也就是说我们可以求得所有的\(g ( n )\),也就是这个集合中所有是\(n\)的倍数的异或值.

注意一个事实:如果我们设\(w ( m ) = \prod_{ p \in \mathrm{ prime } , p | m } p\),那么我们就可以按照\(w\)的不同将所有数划分为若干个集合,每个集合在每次查询的时候要么都不被异或要么都被异或.这也告诉我们:我们只能求出每个集合中被选进\(A\)的这些数的异或值,而不能分开得知它们.接下来考虑如何知道这个,不妨设\(S ( n ) = \{ x | w ( x ) = n \}\),又设\(h ( n ) = \bigoplus_{ i \in A , i \in S ( n ) } i\).考虑用\(g ( n )\)表示\(h ( n )\),我们有:

\[ g ( n ) = \bigoplus_{ n | d } | \mu ( \frac{ d }{ n } ) | h ( d ) \]

反演,有\(h ( n ) = \bigoplus_{ n | d } g ( d ) \\\).于是我们可以求得所有的\(h ( n )\)了.

现在的问题在于:对于数\(n , \mu ( n ) \ne 0\),我们要在\(S ( n )\)中选出若干个数,使得它们的异或和为\(h ( n )\),并且选出的数字总共有\(| A |\)个.

然后是根据数据随机,拿每个集合的线性基随机一下自由元,然后对着构造.多随机几次,最后做背包.

多重子集反演

\(S\)为可重集合.

一般形式:定义\(\mu ( S )\),若\(S\)包含重复元素则为\(0\),否则为\(( - 1 )^{ | S | }\).

$$ \[\begin{aligned} f ( S ) & = \sum_{ T \subseteq S } g ( T ) \Leftrightarrow g ( S ) = \sum_{ T \subseteq S } \mu ( S - T ) f ( T ) \\ \end{aligned}\]

$$

证明:

根据莫比乌斯反演,这个是显然的.

单位根反演(离散傅里叶变换)

一般形式(\(\omega_n = e^{ \frac{ 2 \pi i }{ n } }\)):

\[ f_m = \sum_{ k = 0 }^{ n - 1 } \omega_n^{ mk } g_k \Leftrightarrow g_m = \frac{ 1 }{ n } \sum_{ k = 0 }^{ n - 1 } \omega_n^{ - mk } f_k \]

可以发现这个式子其实就是FFT时所做的DFT与IDFT.

一般情况

考虑莫比乌斯反演的过程,我们实际上使用的是\([ m | n ] \sum_{ d | \frac{ n }{ m } } \mu ( d ) = [ n = m ] \\\).

\(c = md\),左边\(= \sum_{ c | n } [ m | c ] \mu ( \frac{ c }{ m } ) = \sum ( [ c | n ] ) ( [ m | c ] \mu ( \frac{ c }{ m } ) ) \\\).

\(A_{ c , n } = [ c | n ]\),\(B_{ m , c } = [ m | c ] \mu ( \frac{ c }{ m } ) \\\),那我们有\(BA = I\).

刚才的过程相当于:

$$ \[\begin{aligned} Ax & = b \\ x & = Ix \\ x & = ( BA ) x \\ x & = B ( Ax ) \\ x & = Bb \\ \end{aligned}\]

$$

无论是二项式反演还是莫比乌斯反演,他们都满足\(f ( n )\)所依赖的\(g ( k )\)\(k \leq n \\\).

根据上面的情况,我们发现\(A\)是一个下三角矩阵,\(B\)\(A^{ - 1 }\).

现在来推导满足\(k \leq n\)的一般情况反演:

$$ \[\begin{aligned} f ( n ) & = \sum_{ k = 1 }^n a_{ n , k } g ( k ) \\ \end{aligned}\]

$$

不妨设算子\(\mu ( n , m )\),满足\(\sum_{ k = 1 }^n a_{ n , k } \mu ( k , m ) = \sum_{ k = 1 }^n \mu ( n , k ) a_{ k , m } = [ n = m ] \\\).

\(AB = BA = I \\\).

$$ \[\begin{aligned} g ( n ) & = \sum_{ m = 1 }^n [ n = m ] g ( m ) \\ & = \sum_{ m = 1 }^n \sum_{ k = 1 }^n \mu ( n , k ) a_{ k , m } g ( m ) \\ & = \sum_{ k = 1 }^n \mu ( n , k ) f ( k ) \\ \end{aligned}\]

$$

由上我们发现,反演解决了一些在下标上的二元运算卷积:

$$ \[\begin{aligned} c_r & = \sum_{ p , q } [ f ( p , q ) = r ] a_p b_q \\ \end{aligned}\]

$$

而我们需要把\(f\)分成两个独立的部分,通常正变换一下,处理一下,逆变换回来.

容斥

一般形式

即:将求并集中元素个数转化成了求交集中元素个数.

我们有:\(\mid \bigcup_{ i = 1 }^n S_i \mid = \sum_{ T \subseteq \{ 1 , . . . , n \},T\ne \emptyset } ( - 1 )^{ | T - 1 | } \mid \bigcap_{ p \in T } S_p \mid\).

证明:我们考虑对于每个元素,看它对最终答案的贡献.假设它所属\(m\)个集合\(S_1 , . . . , S_m\),而除了这些集合以外的集合,

\[ \begin{aligned} cnt & = \sum_{ i = 1 }^m ( - 1 )^{ i - 1 } \binom{ m }{ i } \\ & = \binom{ m }{ 0 } - \sum_{ i = 0 }^m ( - 1 )^i \binom{ m }{ i } \\ & = 1 - [ m = 0 ] \end{aligned} \]

显然,当这个元素被包含的时候,贡献为\(1\),反之贡献为\(0\).

如果我们定义一类在集合上的函数\(F ( S ) = \sum_{ p \in S } F ( p )\),那么自然也有:

\[ F ( \bigcup_{ i = 1 }^n S_i ) = \sum_{ T \subseteq \{ 1 , . . . , n \} } ( - 1 )^{ | T | - 1 } F ( \bigcap_{ p \in T } S_p ) \]

另外,我们上面的做法是:当交集好求时求并集.我们还可以使用一步补集转化:

\[ \mid \bigcap_{ i = 1 }^n S_i \mid = | U | - \mid \bigcup_{ i = 1 }^n \overline{ S_i } \mid \]

这样我们同样可以在并集好求的时候求交集.

会发现容斥和二项式反演是很像的.但是不一样的是,容斥是从集合的角度考虑,更注重单个元素的贡献;二项式反演是从函数的角度考虑,更关注函数之间的转化.

Example1(不定方程非负整数解计数)

考虑不定方程\(\sum_{ i = 1 }^n x_i = m\),和\(n\)个限制条件\(x_i \leq b_i\),其中\(m\)\(b_i\)都是非负整数,求该方程的非负整数解的数目.

首先,我们需要找出全集\(U\),以及刻画\(U\)中元素的\(P_i\)(条件):

  1. \(U\)是满足\(\sum_{ i = 1 }^n x_i = m\)的所有非负整数解;

  2. 对于每个变量\(i\),都对应一个\(P_i = [ x_i \leq b_i ]\).

设所有满足\(P_i\)的解构成集合\(S_i\),那么我们需要求解的值就是\(\mid \bigcap_{ i = 1 }^n S_i \mid\).而\(\mid U \mid\)显然是\(\binom{ m + n - 1 }{ n - 1 }\).我们有:\(\mid \bigcap_{ i = 1 }^n S_i \mid = | U | - \mid \bigcup_{ i = 1 }^n \overline{ S_i } \mid\).考虑对\(\mid \bigcup_{ i = 1 }^n \overline{ S_i } \mid\)使用容斥原理,注意到\(\overline{ S_i }\)的意义是满足\(x_{ i } \geq b_{ i } + 1\)的解的数目.换句话说也就是部分变量有下界限制,那直接左右两边同时减去下界即可.于是枚举子集即可实现.

欸,等一下,咋想到的补集转化,又是咋想到要用容斥的捏?

我们冷静一下,首先补集转化和容斥都是一个思想:正难则反.我们要求满足条件的个数,就先想一下能不能求不满足条件的个数,然后拿总的个数减去.然后注意到不满足条件的意义是:有至少一个不满足,这样就很可以容斥了.

Example2(错排问题)

我们考虑从容斥的角度再次认识一下错排.

首先,我们需要找出全集\(U\),以及刻画\(U\)中元素的\(P_i\)(条件):

  1. \(U\)是长度为\(n\)的所有排列;

  2. 对于每个变量\(i\),都对应一个\(P_i = [ p_i \ne i ]\).

注意到所求仍然是\(\mid \bigcap_{ i = 1 }^n S_i \mid\).于是我们仍然试图\(| \bigcap_{ k = 1 }^m \overline{ S_{ a_k } } |\).考虑其意义,也即:有\(m\)个位置被确定了,而其它位置没有限制,于是\(| \bigcap_{ k = 1 }^m \overline{ S_{ a_k } } | = \binom{ n }{ m } ( n - m ) !\).根据容斥,自然有:\(d_n = n ! - \sum_{ m = 1 }^n ( - 1 )^{ m - 1 } \binom{ n }{ m } ( n - m ) ! = n ! \sum_{ m = 0 }^n \cfrac{ ( - 1 )^m }{ m ! }\).

Example3(bzoj3622已经没有什么好害怕的了)

首先可以用dp+双指针得到\(f_i\)表示勒令\(i\)对满足条件的方案数.把\(k\)的定义改为恰好\(k\)对满足条件的显然是同强度的.

我们接下来仍然考虑容斥,首先,我们需要找出全集\(U\),以及刻画\(U\)中元素的\(P_i\)(条件).

等一下,这个好像不好刻画?

我们先回归一下容斥的本质:考虑每个元素的贡献.注意到恰好\(a\)对的方案会被钦定\(b\)对的方案计算\(\binom{ b }{ a }\)次.我们再考虑一种方式理解容斥:我们一步一步把正确的答案消出来:简单来说,我第一步让所有恰好为\(k\)的方案贡献为\(1\),其它的可能也有贡献,但我们忽略他们.第二步让所有恰好为\(k + 1\)的方案贡献为\(0\),第三步以此类推.于是这个题,我们考虑也这么做:这样第一步令\(ans = f_k\),第二步除去其中被多算的\(k + 1\),这一步令\(ans - = \binom{ k + 1 }{ k } f_{ k + 1 }\).这个时候,我们再考虑\(k + 2\)的贡献:它将在\(f_k\)时贡献\(\binom{ k + 2 }{ k }\)次,在\(f_{ k + 1 }\)时贡献\(- \binom{ k + 2 }{ k + 1 } \binom{ k + 1 }{ k } = - \binom{ k + 2 }{ k } \binom{ 2 }{ 1 }\)次,那它现在的贡献还有:\(- \binom{ k + 2 }{ k }\)次.以此类推,可以得到\(ans = \sum_{ i = k }^n f_i ( - 1 )^{ i - k } \binom{ i }{ k }\).

等一下,这也太麻烦了,就不能从集合的角度分析嘛?

冷静一下,如果我们要做容斥,我们必须考虑每个元素单独的贡献,但是在这个题中,每个元素并没有单独的贡献,而是整个集合需要满足性质才能贡献.也就是说,我们无法分析每个\(P_i\).而考虑集合就需要将集合分类,从而使用二项式反演.

换句话说,这个定义在集合上的函数并不满足可加性.

换句话说,我们要用容斥,就一定要刻画\(P_i\),因为只有这个时候,我们才能通过分析满不满足\(P_i\)的解集的交并来实现.

再换句话说,大部分的所谓的容斥其实都和集合没啥关系,我们做容斥就是需要逐个考虑贡献,把它们贡献全都杀成\(1 / 0\)就行.

Example4(HAOI2008硬币购物)

如果直接对于每次询问暴力做,复杂度显然是\(O ( 4 ns )\),无法接受.于是考虑预处理来降低单词询问复杂度.

注意到硬币数量很少,并且每个硬币的贡献可以独立计算.我们完全可以刻画\(P_i = [ use_i \leq d_i ]\),从而可以用容斥做.复杂度\(O ( 4 s + n 2^4 )\).

Example5

Alice和Bob在玩游戏,他们有一个\(n\)个点的无向完全图,设所有的边组成了集合\(E\),他们想取遍\(E\)的所有非空子集,对某个集合\(S\)有一个估价\(f ( S )\):考虑\(n\)个点与\(S\)中的边组成的图,我们用\(m\)种颜色对所有点染色,其中同一个连通块的点必须染成一种颜色,那么\(f ( S )\)等于这个图的染色方案数.同时,Alice喜欢奇数,所以当\(| S |\)为奇数时,Alice的分值加上\(f ( S )\),否则Alice的分值减去\(f ( S )\),求最后的分值.\(( n , m \leq 10^6 )\).

一开始抄题的时候没有写染色而是直接写”设\(k\)为连通块个数,则\(f ( S ) = m^k\).”然后发现做不了,因为\(| S |\)相同的\(f ( S )\)不尽相同,而且可能情况还蛮多的.冷静一下,注意到连通块这个性质太强了:如果我们把它放到指数上,那应该会做得很痛苦.所以我们考虑每有一个连通块就乘上一个\(m\),这个看上去就简单一些.

但是这样好像还是不太好做,毕竟现在我们面对的还是一个难以转化为计数问题的图论问题,只是把问题的单位元素从图变成了连通块.那我们能不能再进一步:把单位元素换成单点呢?

考虑由于连通块要染一种颜色,那\(x \leftrightarrow y \Rightarrow col_x = col_y\).注意到这是一个单位元素更小的限制条件!并且我们发现我们将与\(- 1\)有关的单位元素(从一开始就是点)和与\(f\)有关的单位元素统一起来了.这也提示我们做计数的时候,尤其是做容斥的计数的时候,最好先将单位元统一,这样后面才可能更容易做.

接下来就可以写式子了,令\(F ( C )\)表示在\(C\)情况下的染色方案,\(T_{ ( i , j ) }\)表示满足边\(( i , j )\)限制的解集:

\[ ans = \sum_{ \emptyset \ne S \subseteq E } ( - 1 )^{ | S | - 1 } F ( \bigcap_{ ( i , j ) \in S } T_{ ( i , j ) } ) \]

冷静一下!这个东西和容斥长得那叫一个一模一样啊.我们看看能不能逆向分析出\(ans\)的意义:显然是\(F ( \bigcup_{ i = 1 }^{ m } P_i )\).也就是完全图中至少有两个点颜色相同的染色数.根据补集转化,我们只需求出两两点不相同的染色数即可.所以最后的答案就是\(m^n - m^{ \underline{ n } }\).

Example6

\(\varphi ( n )\).

考虑这么一个事实:假设\(n = \prod p_i^{ q_i }\),注意到令\(P_i = [ \gcd ( i , n ) = 1 ]\),我们所求也就是\(\mid \bigcap_{ i = 1 }^n S_i \mid\).于是可以用上面的方法做.另外,这里的做法引出莫比乌斯反演.

Example7(AGC058D)

直接容斥好像不太可做,我们把容斥中的条件改为有多少个极长的形如\(ABCABCAB . . .\)这样的串.

乍一看这个极长的条件好像巨难满足,但实际上我们冷静一下,我们只需要满足这个串长度大于等于\(3\)并且开头不能往前延申就可以了,后面其实是没啥必要管的.

拿组合数算一算.

Example8(AGC035F)

显然问题只在于重复计算的问题.我们先将所有状态做一个双射:对于一个网格,唯一可能被重复计算的只可能是一个拐角的\(1\),我们让这种情况下的行尽可能长.

然后捏?注意到这样的话一个拐角的角一定是行了,是列就一定不合法,我们考虑把不合法的列杀了.

于是做一下容斥,答案是\(\sum_{ i = 0 }^{ \min ( n , m ) } ( - 1 )^i \binom{ n }{ i } \binom{ m }{ i } i ! ( m + 1 )^{ n - i } ( n + 1 )^{ m - i }\).

Example9

给定若干个限制条件\(( x , y )\),表示\(a_x = y\)\(a_y = x\)必须满足至少一个,求排列方案数.

首先\(i \rightarrow p_i\)把排列转化成图,这样上面的限制条件也就是有一些无向的链和环,最后定向.一开始以为随便做做,思考一下注意到如果有长度为\(2\)的链,它自己成环的话是不用\(\times 2\)的.

这咋办.一个办法是:我们考虑容斥,先随便放进去,最后再钦定若干个自己成环.诶等一下为啥这个容斥是对的?因为系数是\(\times 2\),所以一个有\(1\)个单独成环的状态会被随便放的情况恰好多算一次.类似可以做容斥.

当然,也可以考虑先把其它的合并,最后做长度为\(2\)的链,但是!一开始一定要钦定有序,最后再用组合数统一算答案.因为一开始带着顺序做很难做.

Example10([AGC036F] Square Constraints)

由题意得:\(n^2 - i^2 \leq P_i^2 \leq ( 2 n )^2 - i^2\).

当一个东西有上界又有下界的时候可以想到容斥.问题转化为只有上界.假设最后所有的上界为\(l_i\),那么只有上界的答案应该是什么呢?将\(l\)从小到大排序,答案就是\(\prod_{ i = 0 }^{ 2 n - 1 } ( l_i - i )\).(注意到必须满足\(l_{ 2 n - 1 } = 2 n - 1\).)

但是这个东西和容斥怎么结合起来呢?我们将限制放到二维平面上,注意到上下界的限制其实是两个\(\frac{ 1 }{ 4 }\)的圆弧.而通过圆弧的性质不难看出:最终的\(l\)分为三部分:在下半部分圆弧上的,在上半部分圆弧后面的,在上半部分圆弧前面的.而如果想知道\(l\)按照顺序排序,我们只需要对前两部分做归并,然后将最后一部分直接放到后面即可.于是我们考虑按照\(l\)的大小为顺序进行一个类似归并的东西,每次判断当前下半部分圆弧是否要往上加点即可.这样我们可以处理前两部分对答案的贡献,但问题在于第三部分对答案的贡献怎么做,我们需要找到第三部分上的点在排序后的位置.我们预先枚举容斥集合的大小即可,这样就可以快速算出这个东西,于是复杂度\(O ( n^3 )\).

Example11([23省选第一轮集训day4]C带劲的旅行)

(下面将\(n\)\(m\)反着写)

\(p = \frac{ 2 k }{ n } , q = n - p\).

首先注意到期望\(= P [ len \geq 1 ] + P [ len \geq 2 ] + \cdots\).

考虑如何计算\(P [ len \geq x ]\),如果我们设\(a_i\)表示以\(i\)作为开头的极长的带劲的长度大于等于\(x\)的序列的集合,那么最后无非是要求所有\(a\)的并.考虑用容斥做到求所有\(a\)的交.不过要注意讨论一下是不是第一个点.

Example12

给定\(n , k\)\(n\)个点各自的颜色,对有编号无根树计数,要求相同颜色组成的连通块大小不超过\(k\).\(n \leq 300\).

著名结论:\(n\)个点\(m\)个连通块任意连边成树的方案数是\(n^{ m - 2 } \prod s\),其中\(s\)是每个连通块的大小.但是,如果我们强行对每种颜色分成若干连通块,我们要防止它们之间有边.这就是我一开始没做出来的原因:要容斥的根本不是树的大小不能超过\(k\),由于树的形态多变,这个是不能维护的!正确的做法是找到若干个相同颜色的大小小于等于\(k\)的连通块,要求它们两两无边.甚至根本就不是它们可以连边但是大小不能超过\(k\),我们要容斥的东西一定要好算,简单.

然后就做完了,每次暴力合并若干个颜色相同的块,容斥系数\(( - 1 )^{ 块 数 - 1 }\).

容斥是一个层层递进的东西,我们每一步都是基于上一步的限制:它本身就是一个求解集的东西.

Min-Max容斥

对于:

\[ \mid \bigcup_{ i = 1 }^n S_i \mid = \sum_{ T \subseteq \{ 1 , . . . , n \} } ( - 1 )^{ | T - 1 | } \mid \bigcap_{ p \in T } S_p \mid \]

考虑一个特例:\(S_i = \{ 1 , 2 , \cdots , a_i \}\),那么上面的式子导出min-max容斥(我们设\(S = \{ a_1 , a_2 , \cdots , a_n \}\))(第二个式子可以把前缀改成后缀):

\[ \begin{aligned} \max ( S ) & = \sum_{ T \subseteq S , T \ne \emptyset } ( - 1 )^{ | T | - 1 } \min ( T ) \\ \min ( S ) & = \sum_{ T \subseteq S , T \ne \emptyset } ( - 1 )^{ | T | - 1 } \max ( T ) \end{aligned} \]

由于是集合,这个式子在期望意义下同样成立:

\[ \begin{aligned} E ( \max \{ S \} ) & = \sum_{ T \subseteq S , T \ne \emptyset } ( - 1 )^{ | T | - 1 } E ( \min \{ S \} ) \\ E ( \min \{ S \} ) & = \sum_{ T \subseteq S , T \ne \emptyset } ( - 1 )^{ | T | - 1 } E ( \max \{ S \} ) \end{aligned} \]

进一步,这个式子可不止能求min-max的转化,它可以求出集合中第k大的数字:

\[ \begin{aligned} kth \max \{ S \} & = \sum_{ T \subseteq S , T \ne \emptyset } ( - 1 )^{ | T | - k } \binom{ | T | - 1 }{ k - 1 } \min \{ T \} \\ kth \min \{ S \} & = \sum_{ T \subseteq S , T \ne \emptyset } ( - 1 )^{ | T | - k } \binom{ | T | - 1 }{ k - 1 } \max \{ T \} \\ E ( kth \max \{ S \} ) & = \sum_{ T \subseteq S , T \ne \emptyset } ( - 1 )^{ | T | - k } \binom{ | T | - 1 }{ k - 1 } E ( \min \{ T \} ) \\ E ( kth \min \{ S \} ) & = \sum_{ T \subseteq S , T \ne \emptyset } ( - 1 )^{ | T | - k } \binom{ | T | - 1 }{ k - 1 } E ( \max \{ T \} ) \end{aligned} \]

原理是消掉前\(k - 1\)大的数字,让他们的贡献为\(0\),剩下的配一下容斥系数.

Example1([23省选10连测 day6]A)

不妨设\(tim_i\)\([ i , i + 1 ]\)第一次被覆盖的时间,答案就是:

\[ E ( \max_{ i = 1 }^{ n - 1 } \{ tim_i \} ) = \sum_{ T \subseteq \{ 1 , 2 , \cdots , n - 1 \} , T \ne \emptyset } ( - 1 )^{ | T | - 1 } E ( \min_{ j \in T } \{ tim_j \} ) \]

\(f ( S )\)为有多少个区间能覆盖至少一个\([ i , i + 1 ] , i \in S\),考虑\(E = p_{ [ t \geq 0 ] } + p_{ [ t \geq 1 ] } + p_{ [ t \geq 2 ] } + \cdots\),于是\(E ( \min_{ j \in S } \{ tim_j \} ) = \frac{ m }{ f ( S ) }\).

于是:

\[ \begin{aligned} ans & = \sum_{ T \subseteq \{ 1 , 2 , \cdots , n - 1 \} , T \ne \emptyset } ( - 1 )^{ | T | - 1 } f ( T ) \\ & = \sum_{ k = 0 }^m \frac{ m }{ k } \sum_{ T \subseteq \{ 1 , 2 , \cdots , n - 1 \} , T \ne \emptyset , f ( T ) = k } ( - 1 )^{ | T | - 1 } \end{aligned} \]

注意到\(f ( S )\)可能不那么好求,我们求\(g ( S ) = m - f ( S )\),也就是不包含任何一个\([ i , i + 1 ] , i \in S\)的区间个数,我们有:

\[ ans = \sum_{ k = 0 }^m \frac{ m }{ m - k } \sum_{ T \subseteq \{ 1 , 2 , \cdots , n - 1 \} , T \ne \emptyset , g ( T ) = k } ( - 1 )^{ | T | - 1 } \]

这里已经不难写出\(O ( n^3 )\)的dp了.

那么怎么优化呢?设\(dp_{ i , j }\)表示只考虑\([ 1 , i ]\)时(\([ i - 1 , i ]\)必选),\(\sum_{ g ( T ) = j } ( - 1 )^{ | T | - 1 }\)的答案,不难发现每次加入一个区间\([ l , r ]\)就会让\(dp_{ i , j } , i < = l\)\(dp_{ r , j + 1 }\)的贡献乘一个\(1\).

如何处理这个事情?我们用类似多项式的东西,前者相当于平移多项式系数,后者相当于标量乘法,然后拿线段树维护和,复杂度\(O ( nm \log n )\).

反射容斥

一般形式:给定二维平面上两个点\(S\)\(T\),其中\(T\)\(S\)的右方,给定两条线\(y = a\)\(y = b\),每次可以向右上或者右下走一步,求不碰线的从\(S\)\(T\)的方案数.

我们不妨设\(A\)表示一定碰了一次上界的方案数,\(B\)表示一定碰了一次下界的方案数,\(AB\)表示一定碰了一次上界后碰了一次下界的方案数……

最后的答案就是随便走\(- A - B + AB + BA - ABA - BAB . . .\).

考虑设步数为\(n\),那显然长度最多为\(\cfrac{ n }{ a - b }\).

Bash游戏

\(A\)\(B\),有\(n\)颗石子,每次可以取\(x\)颗,其中\(1 \leq x \leq m \\\),求\(A\)是否能赢.

考虑直接令石子数量为状态,有\(SG ( x ) = mex \{ SG ( y ) | \max \{ 0 , x - m \} \leq y \leq x - 1 \} \\\),注意到\(SG ( x ) = 0\)当且仅当\(x \equiv 0 ( \mod m + 1 )\).

我们使用数学归纳证明:

\(0 \leq x \leq m\)时,显然成立.

而对于\(x\),如果\(x \equiv 0 ( \mod m + 1 ) \\\),那么集合\(S = \{ y \in \mathbb{ Z } | \max \{ 0 , x - m \} \leq y \leq x - 1 \}\)中一定\(\nexists y\)满足\(y \equiv 0 ( \mod m + 1 ) \\\).

也就是\(\nexists y\)满足\(SG ( y ) = 0\),那么\(SG ( n ) = 0\).反之,一定存在.

Nim游戏

\(A\)\(B\),有\(n\)堆石子,第\(i\)堆石子有\(x_i\)个石子.每次可以任选一堆取走若干个石子,最后不能取的人输.求先手是否必胜.

注意到如果\(x\)均等于\(0\)一定先手必败.考虑令\(w = x_1 \oplus x_2 \oplus . . . \oplus x_n\)(\(w\)即为全游戏的\(SG\)值),那么先手必败当且仅当\(w = 0 \\\).

证明:

只需证明当\(w \ne 0\)时一定存在一种方法使得\(w = 0 \\\).

考虑\(w\)的最高位为第\(k\)位,那么一定存在一个\(x_i\)的第\(k\)位为\(1\).将它改为\(0\),然后这个\(x_i\)的后面几位可以随意更改.

Example1(Nimk游戏)

\(A\)\(B\),有\(n\)堆石子,第\(i\)堆石子有\(x_i\)个石子.每次可以任选不超过\(k\)堆取走若干个石子,最后不能取的人输.

\(x_i\)写成二进制,如果每一位的\(1\)的个数均是\(k + 1\)的倍数,那么先手一定必败.道理是差不多的.

Example2(Multi-Nim游戏)

Nim游戏,但是玩家每回合可以将任意一堆石子数量大于等于\(2\)的石子堆分成任意两堆不为空的石子堆.没法操作的人输.

本质仍然是SG游戏,我们正常做就行.

\(SG ( x ) = mex \{ \{ SG ( v ) | x \rightarrow v \} , \{ SG ( x - i ) \oplus SG ( i ) | 1 \leq i < x \} \} \\\).

找一下规律可以发现:

$$ \[\begin{aligned} SG ( x ) & = \begin{cases} x - 1 & x \equiv 0 ( \mod 4 ) \\ x & x \equiv 1 或 2 ( \mod 4 ) \\ x + 1 & x \equiv 3 ( \mod 4 ) \\ \end{cases} \\ \end{aligned}\]

$$

不妨设当\(x \leq 4 k\)时结论成立.

\(x = 4 k + 1\)时,前半部分一定是取遍了\([ 1 , 4 k ]\).

但是一定不存在\(a\)\(b\)满足\(a + b = 4 k + 1\)并且\(SG ( a ) \oplus SG ( b ) = 4 k + 1\).讨论一下\(a\)\(b\)\(\mod 4\)意义下的值就会发现不可能.

其他的是同理的.

SG游戏

\(n\)个DAG,每个DAG只有一个起始点,起始点上有一枚棋子.\(A\)\(B\)每次可以选一个图,将上面的棋子沿DAG移动一条边,不能移动的人输.

直接使用\(SG ( u ) = mex \{ SG ( v ) | u \rightarrow v \}\).

那么先手必败当且仅当所有DAG初始节点的SG异或起来是\(0\).

首先如果\(SG ( u ) = x\),那么\(\forall 0 \leq y < x\),\(\exists v\)使得\(u \rightarrow v\)\(SG ( v ) = y\).可以发现这就如同Nim游戏了.

但是与Nim游戏不同的是,可能\(\exists y > x\),但是仍然可以转移到.

但在这种情况下,我可以继续转移到一个\(u '\)使得\(SG ( u ' ) = x\),因此异或值不变.

Example1(Anti-SG游戏)

SG游戏,但是不能取的人赢.

SJ定理:

先手必胜当且仅当下面两个条件满足一个:

  1. 游戏的SG函数不为\(0\)且游戏中某个单一游戏的SG函数大于\(1\).

  2. 游戏的SG函数为\(0\)且游戏中没有单一游戏的SG函数大于\(1\).

如果没有单一游戏的SG函数大于\(1\),那么显然游戏的SG函数为\(0\)就赢了,否则就输了.

而如果SG函数为\(0\)且存在某个单一游戏的SG函数大于\(1\),一定是输的.

因为这个情况下,后手先按照正常\(SG\)游戏压着先手,最后一定会剩两堆一样大于\(1\)的,无论你怎么选,对手都可以压着你.如果你把一堆全选了,此时对手就可以把另一堆剩下一个,这样就必输;如果你把这一堆选的只剩下一个,对手就可以把它那一堆全选了,这样就也是必输的.

Example2(Every-SG)

SG游戏,但是每次每个能移动的游戏都必须移动,不能移动任何游戏的人输.

对于每个子游戏,如果先手必胜,先手一定会尽可能多争取时间.

反之,先手一定会尽可能早结束游戏.

\(DAG\)上dp的时候除了\(SG\)我们再加一维表示时间耗费,就可以dp了.

Example2.5(Every-SG)

n个游戏,每个游戏两堆石子,每次可以从大的那堆中取小的那堆石子大小的整数倍的石子.

直接套用Every-SG的做法就行.

Example3(Nim on tree)

一棵有根树两个人,每次可以挑一棵真子树删掉,不能操作者输.

结论:\(SG ( u ) = \bigoplus_{ u \rightarrow v } ( SG ( v ) + 1 )\).

考虑归纳假设.如果\(u\)只有\(v\)一个儿子.那么要么将\(v\)子树全删,要么删一部分,有:

\[ SG ( u ) = mex ( x | x = 0 \lor 0 \leq x - 1 < SG ( v ) ) = SG ( v ) + 1 \]

而如果有多个儿子,则每个儿子都相当于是一个SG子游戏,异或起来即可.

另一种理解方式:考虑只有一个儿子的情况,那么相当于这个儿子的所有状态都向终止节点连了一条边,终止节点的\(SG\)\(0\),而显然\(SG\)图中的其它节点的\(SG\)均要\(+ 1\).

Example4

\(n\)个有根仙人掌,保证所有的环与树的结构只有一个公共点(环只有一条连到环外的边).

两个人分别操作删边,与根不连通的边都被删掉.

结论:奇环\(SG = 1\),偶环\(SG = 0\).

这么考虑:边数为\(k\)的链的\(SG\)\(k\).

而拆开奇环后,你得到的两条链奇偶性一定相同,因而不可能得到\(1\).偶环同理,不可能得到\(0\).

Example5

无向图,每次删掉一条边以及与根节点不连通的部分,无法操作者输.

考虑Example2.

Fusion定理:将偶环替换成一个新点,奇环替换成一个新点连出去一条边,做边双.对于一个边双,\(SG\)值只和他边的奇偶性有关.证明大概和上面一样.

斐波那契博弈

一个数\(N\),两个人轮流令他减去一个数,第一次不能减完,每次减的不能超过上一次的两倍.

不能操作者输.

结论为:当且仅当\(N\)是斐波那契数时,先手必败.

考虑归纳证明:

先证明当\(N\)是斐波那契数时必败,不妨假设\(N = N_0 + N_1\),

考虑将\(N\)看成两堆,因为如果第一次取走了大于\(N_1\)颗石子,由于\(N_0 \leq N_1 \\\),则后手第二步可以全取走,必败.

并且一开始先手一定要在\(N_0\)堆取石子,原因是如果取了大于\(N_0\)颗石子,由于\(N = N_0 + N_1 \leq 3 N_0 \\\).这样下一步后手就可以全取完.

那么现在先手应该开始取\(N_0\)这一堆,如果在这一堆取的过程中,先手一直取得不超过\(N_0\)剩下的数,那么根据归纳假设,后手一定可以取走\(N_0\)堆的最后一个石子,此时局面变成了只剩\(N_1\)颗石子.只要此时先手不能一次取走\(N_1\)颗石子,先手就必败.而后手最后一步拿走石子最多会拿走\(\frac{ 2 }{ 3 } N_0\)的石子,但是,\(\frac{ 4 }{ 3 } N_0 < N_1\),因此一定不可能.

否则,仍然是先手取走了\(N_0\)全部石子,又当了先手取\(N_1\)的石子.仍然是必败的.

齐肯多夫定理:任意一个正整数都可以被表示成若干不连续的斐波那契数之和.

\(N = \sum_{ i = 1 }^k f_{ p_i }\),其中\(p_1 < p_2 < p_3 < . . . < p_k \\\),先手取走\(f_{ p_1 } \\\).由于\(2 f_{ p_1 } < f_{ p_2 }\),因此后手接下来无论如何不可能取得大于等于\(f_{ p_2 } \\\),问题转化为一堆大小为\(f_{ p_2 }\)的石子,此时先手必败.因此原问题的先手必胜.

二分图博弈

给出一张二分图和起点\(S\),\(A\)\(B\)轮流操作,每次操作只能选与上一个被选的点相邻的点,且不能选已经选过的点.

考虑二分图的所有最大匹配,如果在所有的最大匹配的方案中都包含了起点\(S\),那么先手必胜,否则先手必败.

证明:

如果所有匹配都包含\(S\),那么\(A\)只需要每次走到一个和\(S\)匹配的点即可.\(B\)无论如何不可能走到一个不在最大匹配中的点,不然,我们将路径全部取反,就得到了一个最大匹配不变但不包含\(S\)的点,与假设不符.

而如果存在一个匹配不包含\(S\),如果\(A\)仍然第一步走到一个和\(S\)匹配的点那么\(B\)一定能想办法走到一个不在当前\(A\)选择的最大匹配中的点而在一个不包含\(S\)的最大匹配中的点,于是\(B\)必胜.

Example1([2022qbxt国庆Day5]C)

显然,一个人敢抢金条当且仅当没有人敢抢他的金条.假设\(dp_{ S , x } = 0 / 1\)表示目前集合\(S\)中的所有人都已经离场了,而目前金条在\(x\)手中,金条会不会被抢.显然,如果\(\exists y\)满足\(dp_{ S \cup \{ x \} , y } = 0\),也就是金条在\(y\)手里不会被抢,那\(x\)手中的金条必定会被抢.

将这个抢的过程看作二分图博弈中走到相邻的点的过程,于是这个问题等价于二分图博弈.也就是说,如果二分图博弈先手必胜,那么第一个拿到金条的人一定会被抢.

因此,我们需要找到所有与\(S\)匹配的可能出现在最大匹配中的边,对应编号最小的那个点,金条最后一定在他手里.(第一步这么走后,一定能构造出)

这个怎么构造呢,我们考虑先跑一遍dinic求最大匹配,然后做一遍tarjan缩点,然后如果\(S\)\(x\)并未匹配,那么我们判断二者是否在一个强连通分量中,如果在,那他们可以被匹配.

至于判断\(S\)是否一定在其中,只需要先删去\(S\),跑dinic,再在残联网络上加上\(S\),判断是否有新的增广路.

树上博弈

Example1(zr[23省选10连 day1] Clashmas)

注意到删点对树形态的影响,考虑重心

  1. \(n\)为奇数,重心为后手点.

注意到此时后手一定可以通过一些方式维持重心不变,因此后手必胜.

  1. \(n\)为奇数,重心为先手点.

我们不妨设先手是A,后手是B.

考虑一个事实:对于这样一棵树,我们删着删着一定会出现一个时刻使得此时\(n\)为偶数,有两个重心(比如最后只剩下两个点的时刻),根据(4)和(5)的讨论,此时胜负已分.而且不难注意到此时A变为了实际上的后手.

根据(5),如果B掌控了任意一个重心,那A就输了.因此A必定要使当前局面的两个中心均为A的点.考虑原重心的所有儿子,它们有的是A点,有的是B点.由于树的重心的性质,树的重心的移动一定是一点一点挪的,也就是说第一次出现上面的局面的时候,两个重心必有一个是原重心,另一个是原重心的儿子,接下来A和B就要对于另一个重心能取到哪个儿子做争夺.我们不妨设A的点的集合为\(S_A\),B的点的集合为\(S_B\).以原重心为根建树,设其所有儿子组成的集合为\(S_C\),不难发现A能胜利(也就是让两个重心全都属于他)当且仅当\(\sum_{ u \in S_A \cap S_C } siz_u \geq \sum_{ u \in S_B \cap S_C } siz_u\).

原因很简单:A和B必然每次都会去杀属于对方的子树中\(siz\)最大的那棵.由于A有着先手优势,因此只要满足上面的条件,A总能获胜.

  1. \(n\)为偶数,唯一重心,重心为后手点.

类似(2)的讨论,最后一定有某个时刻使得此时\(n\)为偶数,有两个重心(比如最后只剩下两个点的时刻),此时A仍然是先手,根据(5),只要他掌控一个重心就可以获胜.

类似地,不难发现胜利条件等价于(2).

  1. \(n\)为偶数,两个重心,重心均为后手点.

注意到此时整棵树分为两个大小相等的部分,因此后手一定可以维持这个场面不动,后手必胜.

  1. \(n\)为偶数,至少有一个重心是先手点.

注意到此时先手一定存在一种方式开局,使得重心仍为这个先手点,这样就转化为第一种情况,先手必胜.

散题

Problem1([CSP-S2020]贪吃蛇)

首先注意到,如果一个蛇吃完后还不是最小的蛇,那它一定会吃.因为被吃的蛇是单调不降的,而吃蛇的蛇是单调不增的,因此下一个蛇如果要吃,那一定会比它还小,所以至少会先被吃掉,而那条蛇会被吃掉,它就一定不会选,所以无论如何这条蛇都不会被吃掉.

我们考虑如果吃完后变成了最小的蛇后会怎么样,我们设\(f_i\)为还剩\(i\)条蛇的时候能不能吃,那\(f_i = 1\)的话,要么\(i = 2\),要么吃完后不是最小的,要么\(f_{ i - 1 } = 0\).

递归做就好了.另外这题需要复杂度\(O ( n )\),需要用几个队列/双端队列维护.

Problem2([AGC023D]Go Home)

首先,最后一个人要么是最左边的,要么是最右边的.而显然这两边中人数较少的一个将会是最后一个到家的,那么这个人的目标就是帮助另一边的人尽可能快到家,于是会帮着它投票.以此类推不断递归下去.

Problem3(牛客38727E)

首先考虑如果有人作为第\(n - p + 1\)个人复读了,那接下来复读一定不会被惩罚,于是没复读的都会复读,这样这个人就必死.于是最多只会复读\(n - p\)个人.

继续思考,如果有人作为第\(n - 2 p + 1\)个人复读了会怎么样,后面的人也都不会被惩罚了,于是也会继续复读.

以此类推,会发现最后只会有\(n \mod p\)个人复读,并且一定是前\(n \mod p\)在一轮内复读完.

Problem4(arc155D)

考虑直接转移,但是有可能出现在原地转的情况,注意到这种情况我们只需要记录\(f_{ i , j }\)表示当前的\(G\)\(i\),\(G\)的倍数还剩下\(j\)个,然后做转移,再进一步发现我们只关心\(j\)的奇偶性.于是记\(f_{ i , 0 / 1 }\)即可.

这题给我最大的启示是,我们不能假定让双方共同遵守一个”君子协定”,博弈论最重要的就是博弈,不能说我们最后再选倍数之类的,他的转移路线会变化的.

Problem5

给一个“日”字型图,七条边,每条边有一堆石子.每次可以选任意多条不构成环的边,然后将这些边上的石子堆取走任意多个石子.求先手必胜策略,以及如果每条边的石子数量在\([ l_i , r_i ]\),那么有多少种先手必胜的情况.

考虑将这个图分成三部分,上面三条边,中间一条边,下面三条边.那么这三部分一定不能全选至少两部分,不然会构成环.反之一定构不成环.

先手必败当且仅当,这三部分内部的边上石子均相等,并且所有边异或值为\(0\).

否则,考虑将上部分和下部分三条边先全改成相等的,会修改较大的两条边.

接下来,我们剩了三条边,我们只能选择改其中一条,使得他们仨异或值为\(0\).

换句话说,我们现在有\(x_1 , x_2 , x_3\),我们要将其中一个\(x_i\)改为\(y_i\),其他不变,使得他们仨异或值为\(0\).和Nim游戏类似,假设他们仨异或值的最高位为\(k\).那么一定有一个\(x_i\)的第\(k\)位为\(1\),将它改为\(0\),后面就可以随意变换.

思路具体怎么想到的呢,可以发现整个图只有三个环,并且这三个环都可以由这几部分组成.接下来就可以每个部分的\([ l_i , r_i ]\)求个交,用FWT做一遍异或卷积.数位dp也可以做.

Problem6

Nim游戏,但是每堆石子有一个\(K_i\).如果这堆石子剩\(x_i\)个每次最多取\(\lfloor \frac{ x_i }{ K_i } \rfloor\)个石子.求先手是否必胜.

结论是

SG(n-n k,k)&n(k)\

n k&n=0(k)\

\end{cases}\

考虑数学归纳就可以证明.

然后我们就只需要对于\(k\)是否大于\(\sqrt{ n }\)讨论一下,如果\(k < \sqrt{ n }\)暴力,最多只会做\(\sqrt{ n }\)次.否则,意识到此时可以通过求一个区间\([ l , r ]\),满足\(\forall x \in [ l , r ] , \lfloor \frac{ x }{ k } \rfloor\)均相等,加速一下.这种区间最多只会有\(\sqrt{ n }\)个.

Problem7

一个数\(N\),两个人轮流令他减去一个数,第一次不能减完,每次减的不能超过上一次.不能操作者输.

先手必败当且仅当\(N = 2^k\),不然,每次选lowbit即可.

Problem8

A和B,有\(n\)颗石子,每次可以取\(x\)颗,其中\(1 \leq x \leq \lceil \frac{ n }{ 2 } \rceil \\\).

仍然令石子数量为状态,注意到\(SG ( x ) = 0\)当且仅当\(x + 1 = 2^k - 1\),也即\(x = 2^k - 2 \\\).首先,注意到:

$$ \[\begin{aligned} n - \lceil \frac{ n }{ 2 } \rceil & = \lfloor \frac{ n }{ 2 } \rfloor \\ SG ( n ) & = mex \{ SG ( y ) | \lfloor \frac{ n }{ 2 } \rfloor \leq y \leq n - 1 \} \\ \end{aligned}\]

$$

\(n = 2^k - w\),其中:

$$ \[\begin{aligned} - 2^{ k - 1 } + 2 & \leq w \leq 2 \\ \lfloor \frac{ 2^k - w }{ 2 } \rfloor & = 2^{ k - 1 } - \lfloor \frac{ w }{ 2 } \rfloor \\ \end{aligned}\]

$$

\(w = 2\)时,原式\(= 2^{ k - 1 } - 1 > 2^{ k - 1 } - 2 \\\).反之.\(2^k - 2 \leq\)原式.因此数学归纳即可证明.

2024寒假学堂(部分)

Problem4

\(G ( x ) = ( x^2 + x - 1 )^{ 100 } = \sum_{ k = 0 }^{ 200 } a_k x^k\),求\(2 a_0 - a_1 - a_2 + 2 a_3 - a_4 - a_5 + \cdots + 2 a_{ 198 } - a_{ 199 } - a_{ 200 }\).

Solution4

考虑求出\(\sum_{ 0 \leq k \leq 66 }{ a_{ 3 k } }\).直接取三次单位根\(\omega_3 = - \frac{ 1 }{ 2 } + \frac{ \sqrt{ 3 } }{ 2 } i\),自然有\(1 + \omega_3 + \omega_3^2 = 0\),所以\(G ( 1 ) + G ( \omega_3 ) + G ( \omega_3^2 ) = 3 \sum_{ 0 \leq k \leq 66 }{ a_{ 3 k } }\).

所以答案显然是\(G ( \omega_3 ) + G ( \omega_3^2 ) = ( - 2 )^{ 100 } + ( - 2 )^{ 100 } = 2^{ 101 }\).

Problem10

等差数列中,\(a_1 > 0\),公差\(d < 0 , \frac{ a_{ 31 } }{ a_{ 30 } } < - 1\),求最大的正整数\(n\),使得\(S_n > 0\).

Solution10

显然\(S_{ 60 } = 30 ( a_{ 30 } + a_{ 31 } ) < 0 , S_{ 59 } = 59 a_{ 30 } > 0\).

Problem11

全为整数的等差数列,\(d = 4\),求所有满足\(S_n = 2024\)\(n\)的和.

Solution11

\(n ( 2 n - 2 + a_1 ) = 2024 = 2^3 \times 11 \times 23\).显然只要\(n | 2024\)即可.

所有\(n\)的和自然是\(( 1 + 2 + 4 + 8 ) ( 1 + 11 ) ( 1 + 23 ) = 15 \times 12 \times 24 = 4320\).

Problem14

整数数列\(U_n\)满足\(U_0 = 1\),且当\(n \geq 1\)的时候\(U_{ n + 1 } U_{ n - 1 } = kU_n\),其中\(k\)是一个正整数.问能让\(U_{ N } = N\)\(k\)的个数有多少个,其中\(N = 2024\).

Solution14

\(U_{ n + 1 } = \frac{ kU_n }{ U_{ n - 1 } } , \frac{ U_{ n + 1 } }{ U_n } = k \frac{ U_n }{ U_{ n - 1 } } \frac{ 1 }{ U_n }\).

观察上面的式子,不难想到换元后求前缀积,但其实注意到我们可以直接求前缀积,设\(T_n = \prod_{ k = 1 }^n U_k , W_n = U_n \prod_{ k = 1 }^{ n - 2 } U_k\).

注意到\(W_n = kW_{ n - 1 } , W_1 = U_1 , W_n = k^{ n - 1 } U_1\).又注意到\(T_n = kU_{ n - 1 } W_{ n - 1 } = kW_{ n - 1 } \frac{ T_{ n - 1 } }{ T_{ n - 2 } } = k^{ n - 1 } U_1 \frac{ T_{ n - 1 } }{ T_{ n - 2 } } = ( k^{ n - 1 } U_1 ) ( k^{ n - 2 } U_1 ) \frac{ 1 }{ T_{ n - 3 } }\),\(T_{ n - 3 } = ( k^{ n - 4 } U_1 ) ( k^{ n - 5 } U_1 ) \frac{ 1 }{ T_{ n - 6 } }\).所以\(T_{ n } = k^6 T_{ n - 6 }\),所以\(U\)存在长度为\(6\)的循环节.所以\(U_{ N } = \frac{ T_N }{ T_{ N - 1 } } = \frac{ T_2 }{ T_1 } = U_2 = kU_1\).(其实直接暴力找循环节也是可以的)

所以\(k\)需要是\(N\)的因子.

哦,还不如直接找循环节,还要判断这是个整数序列.

\(w = U_1\),则\(U\)的前六项是:\(1 , w , kw , k^2 , \frac{ k^2 }{ w } , \frac{ k }{ w }\).要求\(kw = N , w | k\),所以\(( 11 \times 23 ) | k\),\(k \equiv 0 \pmod{ 4 }\).所以\(k = 4 \times 11 \times 23\)\(k = 8 \times 11 \times 23\).

Problem15

求使方程\(\lfloor \frac{ 10^n }{ x } \rfloor = N = 2024\)恰有两个整数解的正整数\(n\)的个数.

Solution15

我们有:

\[ \begin{aligned} N & \leq \frac{ 10^n }{ x } < N + 1 \\ xN & \leq 10^n < x ( N + 1 ) \\ \frac{ 10^n }{ N + 1 } & < x \leq \frac{ 10^n }{ N } \\ \lfloor \frac{ 10^n }{ N + 1 } \rfloor & < x \leq \lfloor \frac{ 10^n }{ N } \rfloor \\ \lfloor \frac{ 10^n }{ N } \rfloor - \lfloor \frac{ 10^n }{ N + 1 } \rfloor & = 2 \\ \frac{ 10^n }{ N ( N + 1 ) } - \frac{ 10^n \bmod N }{ N } + \frac{ 10^n \bmod{ ( N + 1 ) } }{ N + 1 } & = 2 \end{aligned} \]

显然\(\lfloor \frac{ 10^n }{ N ( N + 1 ) } \rfloor = 1 , 2 , 3\).而\(N ( N + 1 ) = 4098600\),所以只有\(n = 7\)可能满足条件,带入检验可行.

Problem18

用六种颜色给正方形六个面染色,旋转平移后相同算一种方案,要求每个面颜色都不同,求方案数.

Solution18

钦定一个面,然后枚举对面,中间四个是一个环,方案数是\(5 \times 3 ! = 30\).

Problem19

\(f ( x ) = \lfloor 2 x \rfloor + \lfloor 4 x \rfloor + \lfloor 6 x \rfloor + \lfloor 8 x \rfloor , x \in \mathbb{ R }\),求其不超过\(n = 2024\)的正整数取值有多少种.

Solution19

显然\(f ( x + 1 ) = f ( x ) + 20\),因此我们先考虑\(x \in [ 0 , 1 )\)的情况.

手动枚举一下知道此时\(f ( x )\)\(12\)种不同的取值,前六种是\(\{ 0 , 1 , 2 , 4 , 5 , 6 \}\),后六种对应了前六种\(+ 10\).而\(2024 = 101 \times 20 + 4\),所以共有\(101 \times 12 - 1 + 4 = 1215\)种取值.

Problem20

\([ 1 , n ] , n = 2024\)中分别独立随机两个正整数(可以相同)\(a , b\),则求\(3^a + 7^b \equiv 8 \pmod{ 10 }\)的概率.

Solution20

考虑\(\varphi ( 10 ) = 4\),所以原题答案等价于\(n = 4\)的时候的答案.在这\(16\)中可能性中满足条件的只有三种,概率为\(\frac{ 3 }{ 16 }\).

2023强基(部分)

Problem3

已知\(a_1 = \frac{ 5 }{ 2 } , a_{ n + 1 } = a_n^2 - 2\),求\(\lfloor a_n \rfloor \bmod 7 , n = 2023\).

Solution3

这个一看就不是好解的,想都别想直接数学归纳,注意到\(a_n = \frac{ 4^{ 2^{ n - 1 } } + 1 }{ 2^{ 2^{ n - 1 } } }\),那么\(\lfloor a_n \rfloor = 2^{ 2^{ n - 1 } }\).

\(\varphi ( 7 ) = 6 , \varphi ( 6 ) = 2\).由扩展欧拉定理,立刻有:\(2^{ 2^{ 2022 } } \equiv 2^{ 2^{ 2022 } \bmod 6 } \equiv 2^{ 2^{ 6 } } \equiv 16 \equiv 2 \pmod{ 7 }\).

Problem4

\(50\)个队伍两两打比赛,胜一场积分\(+ 1\),负一场积分不变,无平局.

且任取\(27\)支队伍,其中一定有一支队伍负于其它的\(26\)支,也一定有一支队伍胜于其它的\(26\)支.

\(50\)支队伍最少有多少种不同的积分.

Solution4

答案是\(50\).

因为是竞赛图,缩点之后是一条链.

如果所有强连通分量的大小都\(\leq 27\)的话,显然我们全选一个强连通分量就完蛋了.因此所有的强连通分量的大小都\(> 27\),唯一的可能是所有点在一个强连通分量中,我们在其中取出一个长度为\(k\)的简单环,由鸽笼原理,剩下的\(n - k\)个点中至少有\(\frac{ n - k }{ 2 }\)个点对着\(k\)个点只输或者只赢(如果有输有赢就无所谓了),这样的话只需要\(k + \frac{ n - k }{ 2 } \geq 27\)即可,此时\(k \geq 4\)即可.由于这是竞赛图,显然存在长度为\(4\)的简单环.

还有一种更简单的做法,考虑取一个积分最多的点,假设为\(u\).我们任意取一个击败过它的点(如果有的话),假设为\(v\),再取\(25\)个被\(u\)击败的点(显然这些点存在),设这些点集为\(S\).则\(u , v , S\)组成的集合中,有一个点可以击败其它所有点,根据假设,只能是\(v\).由此,可以知道,只要是\(u\)能击败的点,\(v\)一定能击败,而且\(v\)能击败\(u\),因此\(\deg_v > \deg_u\),与假设不符.因此一定不存在一个\(v\)可以击败\(u\).删掉\(u\)后做数学归纳,可知原图一定是拓扑图.

Problem8

一只蚂蚁第一天在\(( 0 , 0 )\),第\(k + 1\)天向上下左右随机一个方向移动\(\frac{ 1 }{ 4^k }\)单位,求第\(n\)天的可能位置数量,\(n = 2023\).

Solution8

不妨设第\(n\)天不同位置数量为\(S_n\),显然只要前面岔开了,后面永远无法走到一个点.所以\(S_1 = 1 , S_{ n + 1 } = 4 S_n , S_{ 2023 } = 4^{ 2022 }\).

Problem10

集合\(U = \{ 1 , 2 , \cdots , n \} , n = 10\),求\(U\)中的满足元素两两互素的三元子集个数.

Solution10

集合是无序的,这个很难搞,我们先从\(U\)中把\(1\)去掉最后再加上.

先考虑可以重复放\(1\)的情况:

$$ \[\begin{aligned} \sum_{ i = 1 }^n \sum_{ j = 1 }^{ n } \sum_{ k = 1 }^{ n } [ \gcd ( i , j ) & = 1 ] [ \gcd ( i , k ) = 1 ] [ \gcd ( j , k ) = 1 ] \\ \end{aligned}\]

$$

这个推下去感觉就头大了,退一步考虑暴力算吧.

先考虑全是奇数的情况,只能从\(1 , 3 , 5 , 7 , 9\)中选,答案应该是\(1 + 2 \binom{ 3 }{ 2 } = 7\).

接下来考虑选一个偶数,如果选\(2 , 4 , 8\)是等价的,答案此时是\(3 ( \binom{ 5 }{ 2 } - 1 ) = 27\).如果选\(6\)的话答案是\(\binom{ 3 }{ 2 } = 3\).如果选\(10\)的话方案数是\(\binom{ 4 }{ 2 } - 1 = 5\),加起来方案数是\(42\).

Problem11

集合\(U = \{ 1 , 2 , \cdots , n \} , n = 366\),则\(U\)的互不相交且各元素之和为\(17\)的倍数的二元子集最多有多少个?

Solution11

考虑\(\lfloor \frac{ 366 }{ 17 } \rfloor = 21 , 366 \equiv 9 \pmod{ 17 }\).答案显然是\(21 \times 8 + 10 + 1 = 179\)个.

Problem12

三个互不相同的数的\(\gcd = 20 , \text{ lcm } = 20000\),求选取这三个数的方案数(顺序不同算不同的方案).

Solution12

显然等价于\(\gcd = 1 , \text{ lcm } = 1000 = 2^3 \times 5^3\).先只分析其中一个质因子,方案应该是\(( 0 , 0 , 3 ) , ( 0 , 1 , 3 ) , ( 0 , 2 , 3 ) , ( 0 , 3 , 3 )\),打乱一下顺序的话就共有\(3 + 6 + 6 + 3 = 18\)种方案.如果可以重复,平方一下得到\(324\).

接下来去掉重复的情况,只有可能两个质因子都相同才会重复,拿上面的三元组算一下,此时方案数共有\(2 \times 2 \times 3 = 12\)种,于是答案为\(312\).

Problem14

\(\lfloor \frac{ k^2 }{ n } \rfloor , k \in [ 1 , n ] , n = 2023\)种有多少个不同的元素.

Solution14

\[ \begin{aligned} \lfloor \frac{ k^2 }{ n } \rfloor & = d \\ d & \leq \frac{ k^2 }{ n } < d + 1 \\ nd & \leq k^2 < n ( d + 1 ) \end{aligned} \]

由于两个完全平方数的差是逐渐增大的,应该存在一个\(k_0\),\(\leq k_0\)\(k\)会扎堆,但是这些\(d\)全都能取到,\(> k_0\)的则不会有两个\(k\)得到相同的元素.所以前者统计不同的\(d\),后者统计不同的\(k\)考虑\(( k + 1 )^2 - k^2 = 2 k + 1\).分界线应该是\(k_0 = 1011\).

所以答案应该是\(n - k_0 + \lfloor \frac{ k_0^2 }{ 2 k_0 + 1 } \rfloor + 1 = 1012 + 506 = 1518\).

Problem15

对四元组\(( a , b , c , d )\)计数,满足\(101 | ( a + b + c + d )\)\(0 < a < b < c < d \leq 101\).

Solution15

这题真的厉害啊.

不妨设\(S_k\)为满足\(( a + b + c + d ) \equiv k \pmod{ 101 }\)的满足\(0 < a < b < c < d \leq 101\)的四元组数量.不难发现\(\sum S_k = \binom{ 101 }{ 4 }\).

注意到\(( a , b , c , d ) \mapsto ( a + 1 , b + 1 , c + 1 , d + 1 )\),注意这里是\(\pmod{ 101 }\)意义下的加法,这是一个双射,所以\(S_{ k } = S_{ k + 4 }\),下标同样也是\(\pmod{ 101 }\)意义下进行的.又因为\(\gcd ( 101 , 4 ) = 1\),所以所有的\(S_k\)均相等.\(S_0 = \frac{ \binom{ 101 }{ 4 } }{ 101 } = 40425\).

Problem16

问方程\(x \lfloor x \rfloor = 6\)的解的个数.

Solution16

\(6 = x \lfloor x \rfloor \geq \lfloor x \rfloor^2\),所以\(\lfloor x \rfloor = \pm 1 , \pm 2\).显然都不可以.所以个数为\(0\).

Problem17

\(R ( n ) = \sum_{ k = 2 }^{ 10 } ( n \bmod k )\),求满足\(R ( n ) = R ( n + 1 )\)的十进制下的两位数\(n\)的个数.

Solution17

\(R ( n )\)\(R ( n + 1 )\),应该是加了若干个\(1\),然后又丢了几个\(k - 1\)这样的.那就一定需要丢掉的数字之和为\(9\).枚举一下,丢了的只有可能是以下情况:\(( 9 ) , ( 7 + 2 ) , ( 6 + 3 ) , ( 5 + 4 ) , ( 4 + 3 + 2 )\),分别对应了\(n + 1\)应该是分别以下数的倍数\(( 9 ) , ( 14 ) , ( 6 ) , ( 20 ) , ( 12 )\),并且和分别要求不是另一些数的倍数,这就去掉了其中的若干个,最后剩下的是:\(( 7 + 2 )\),并且分别不能是以下数字的倍数\(( 3 , 4 , 5 )\).

取一下的话\(n + 1\)可以是:\(14 , 98\),\(n = 13 , 97\),验证一下均合法,所以答案为\(2\).

Problem18

已知\(a < b < c < d\),而\(x , y , z , w\)\(a , b , c , d\)的一个排列,求\(( x - y )^2 + ( y - z )^2 + ( z - w )^2 + ( w - x )^2\)得到的不同数个数.

Solution18

圆排列个数是\(3 ! = 6\)个,只需要判掉相同的圆排列即可.

显然翻转后是相同的,所以最多有三个不同数,排列分别是\(( x , y , z , w ) , ( x , z , w , y ) , ( x , w , y , z )\).

考虑:

\[ \begin{aligned} & ( x - y )^2 + ( y - z )^2 + ( z - w )^2 + ( w - x )^2 \\ = & 2 ( x^2 + z^2 + y^2 + w^2 ) - 2 ( xy + yz + zw + wx ) \end{aligned} \]

显然只要\(xy + yz + zw + wx\)不同,那么两个数就不同.不难判断上面三个数互不相同.

Problem19

已知\(0 < x_1 < x_2 < \cdots < x_9\)\(\sum_{ k = 1 }^9 x_k = 220\),在\(\sum_{ k = 1 }^5 x_k\)最大的前提下,最小化\(x_9 - x_1\).

Solution19

不妨枚举一下\(x_5\)选啥,设\(f ( S , m , k )\)表示选出\(k\)个互不相同的数,使得它们\(\leq m\)且总和为\(S\),是否可行.不难发现\(f ( S , m , k ) = [ \frac{ k ( k + 1 ) }{ 2 } \leq S \leq \frac{ k ( 2 m - k + 1 ) }{ 2 } ]\).

那我们要求的就是:

\[ \begin{aligned} \max_{ 5 \leq x_5 } \{ S | f ( 220 - 4 x_5 - S , + \infty , 4 ) & = 1 \land f ( S - x_5 , x_5 - 1 , 4 ) = 1 \} \\ & = \max_{ 5 \leq x_5 } \{ S | 4 x_5 + S \leq 210 \land 10 + x_5 \leq S \leq 5 x_5 - 10 \} \\ & = \max_{ 5 \leq x_5 } ( \min \{ 5 x_5 - 10 , 210 - 4 x_5 \} ) \end{aligned} \]

立刻得到\(x_5 = 24 , 25 , S = 110\),那么后面的选法就一定了,后面四个数一定是\(26 , 27 , 28 , 29\),只需要让\(x_1\)最大即可

\(x_5 = 24\)时,此时最优显然是\(20 , 21 , 22 , 23 , 24 , 26 , 27 , 28 , 29\),\(x_9 - x_1 = 9\).

Problem20

有一个\(n\)边形,其中有\(\binom{ n }{ 2 }\)条对角线,不存在三线交于一点的情况,问这些对角线将该\(n\)边形分成了多少个部分.\(n = 10\).

Solution20

平面图同样符合欧拉定理.

考虑内部一定多出来了\(\binom{ n }{ 4 }\)个点(任意四个点有且只有一种交法),每交一个点就会多出\(2\)条边,所以多出来了\(2 \binom{ n }{ 4 } + \frac{ n ( n - 3 ) }{ 2 }\)条边.

考虑内部的若干个部分一定是\(a_3\)个三角形,\(a_4\)个四边形,…,\(a_k\)\(k\)边形,总之我们发现:

\[ \begin{cases} \sum_{ j = 3 }^k ( j - 2 ) \pi a_j = ( n - 2 ) \pi + 2 \pi \binom{ n }{ 4 } \\ \sum_{ j = 3 }^k ja_j = n + 4 \binom{ n }{ 4 } + n ( n - 3 ) \end{cases} \]

两式得到:\(\sum_{ j = 3 }^k a_j = \frac{ ( n - 1 ) ( n - 2 ) }{ 2 } + \binom{ n }{ 4 }\).

\(n = 10\)的时候,答案为\(246\).

2024强基(部分)

Problem1

\(\sum_{ i = 1 }^n \lfloor \frac{ 19^i }{ 20 } \rfloor \bmod 7 , n = 2024\).

Solution1

\[ \begin{aligned} & \sum_{ i = 1 }^n \lfloor \frac{ 19^i }{ 20 } \rfloor \\ = & \sum_{ i = 1 }^n \lfloor \frac{ \sum_{ k = 0 }^i 20^k ( - 1 )^{ i - k } \binom{ i }{ k } }{ 20 } \rfloor \\ = & - \lfloor \frac{ n }{ 2 } \rfloor + \sum_{ i = 1 }^{ n } \frac{ 19^i - ( - 1 )^i }{ 20 } \\ = & - \lfloor \frac{ n }{ 2 } \rfloor + \frac{ \frac{ 19 }{ 18 } ( 19^n - 1 ) - ( \frac{ ( - 1 )^n - 1 }{ 2 } ) }{ 20 } \end{aligned} \]

带入\(n = 2024\)\(\bmod 7\),原式为:

\[ \equiv - 4 + \frac{ 5 }{ 4 } ( 1 - 5^n ) \equiv - 4 + 3 ( 1 - 5^n ) \]

注意到\(2024 \bmod 6 = 2\),原式\(\equiv - 4 - 9 \equiv 1\).

Problem3

求长度为\(n\)的排列个数,使得排列中\(\nexists i \in [ 1 , n - 1 ] , a_i = a_{ i + 1 } - 1\).\(n = 8\).

Solution3

一眼容斥,也就是每个长度为\(k\)的连续段的容斥系数应该是\(( - 1 )^{ k - 1 }\).那么设分成了\(w\)个段,总的容斥系数应该是\(( - 1 )^{ n - w }\),答案就是\(f_{ n ' } = \sum_{ w = 1 }^n ( - 1 )^{ n - w } w ! \binom{ n - 1 }{ w - 1 } = \sum_{ w = 0 }^{ n ' } ( - 1 )^{ n ' - w } \binom{ n ' }{ w } ( w + 1 ) ! = n ' ! \sum_{ w = 0 }^{ n ' } \frac{ ( - 1 )^w }{ w ! } ( n ' - w + 1 )\),此时已经能算出答案是\(16687\).

注意到这个形式和错排非常像,类似错排去凑递推公式.设\(g_n\)为错排数量,显然有\(f_{ n } = nf_{ n - 1 } + g_{ n }\),立刻算出答案是\(16687\).

Problem4

已知数列\(1 , 2 , 2 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , \cdots\),求其第\(n\)\(\bmod 5\)的值,\(n = 2024\).

Solution4

考虑第一个值为\(k\)的地方应该在哪里.显然\(a_{ \frac{ k ( k - 1 ) }{ 2 } + 1 } = k\).注意到\(a_{ 2081 } = 65\),所以\(a_n = 64\),其\(\bmod 5 = 4\).

Problem5

求四元组\(( a_1 , a_2 , a_3 , a_4 )\)的个数,满足\(a_1 , a_2 , a_3 , a_4 \in \{ 1 , 2 , 3 \}\),且\(10 < a_1 a_2 a_3 a_4 < 20\).

Solution5

排个序按照字典序开搜,只有三种可能:\(\{ 3 , 3 , 2 , 1 \} , \{ 3 , 2 , 2 , 1 \} , \{ 2 , 2 , 2 , 2 \}\),打乱顺序的话就有\(25\)种可能.

Problem8

\(\mathbb{ R }\)上方程\(x^2 - 13 \lfloor x \rfloor + 11 = 0\)的解的个数.

Solution8

首先注意到\(\lfloor x \rfloor = \frac{ x^2 + 11 }{ 13 }\),那么自然有方程组:

\[ \begin{cases} \frac{ x^2 + 11 }{ 13 } \leq x \\ x < \frac{ x^2 + 11 }{ 13 } + 1 \end{cases} \]

只需要解这个方程组即可.但是这个方程组很难搞.

先考虑\(x^2 \equiv 2 \pmod{ 13 }\)这个性质,由勒让德判别符号,算出该方程在整数范围内无解.

没办法,只能设\(x = \sqrt{ 2 + 13 k }\)的形式,带入有不等式:

\[ \begin{aligned} k - x + 1 & \leq 0 < k - x + 2 \\ 1 & \leq \sqrt{ 2 + 13 k } - k < 2 \\ \begin{cases} 0 < k^2 - 9 k + 2 \\ k^2 - 11 k - 1 \leq 0 \end{cases} \end{aligned} \]

冷静一下!注意到\(0 \leq k \leq 13\),又根据第一个不等式得知大部分\(k\)应该会很大,开始暴力枚举一下,合法的情况有:\(k = 0 , 9 , 10 , 11\),共有四个解.

Problem9

在一个体积为\(1\)的正方体内部找一个点,过这个点作平行于正方体的面的三个平面,这样整个正方体会被分为八个长方体,最小化这八个部分中,体积\(\leq \frac{ 1 }{ 8 }\)的长方体的个数.

Solution9

原本想考虑先横着切一刀,分为一个大部分一个小部分,大部分均分即可,小部分选一个很大的部分,剩下三个部分体积\(\leq \frac{ 1 }{ 8 }\).考虑设这个点是\(( x , x , h )\),那么必然有\(\begin{cases}( 1 - h ) x^2 > \frac{ 1 }{ 8 } \\ h ( 1 - x )^2 > \frac{ 1 }{ 8 }\end{cases}\),化简,只要\(8 > \frac{ 1 }{ x^2 } + \frac{ 1 }{ ( 1 - x )^2 }\)即可,这个根据基本不等式不可能满足,寄了.

但是四个肯定是好构造的,我们直接取\(( 0 . 5 , 0 . 5 , 0 . 1 )\)即可.那么是不是可以证明答案一定\(> 3\)呢?

考虑一个面上的四个长方体,其中较小的两个一定是相邻的.因此,最终体积\(\leq \frac{ 1 }{ 8 }\)的长方体肯定也是相连的.接下来证明三个的不行,只需要设这个点为\(( x , y , h ) , x , y , h \leq \frac{ 1 }{ 2 }\),然后证明\(8 > \frac{ 1 }{ xy } + \frac{ 1 }{ ( 1 - x ) ( 1 - y ) } , x , y \leq \frac{ 1 }{ 2 }\)这个不等式无解即可.

由基本不等式,\(\frac{ 1 }{ xy } + \frac{ 1 }{ ( 1 - x ) ( 1 - y ) } \geq 2 \sqrt{ \frac{ 1 }{ x ( 1 - x ) y ( 1 - y ) } } \geq 2 \sqrt{ 4 \times 4 } = 8\),不符题意.

这样就是最少是四个.

Problem11

\(S ( n )\)表示正整数\(n\)的十进制数码和,求满足\(S ( n ) \equiv S ( n + 1 ) \equiv 0 \pmod{ 5 }\)的最小的\(n\).

Solution11

显然必须发生进位,不妨设\(n = 10^k a + 10^k - 1\),\(a \ne 9 \pmod{ 10 }\),\(S ( n ) = S ( a ) + 9 k , S ( n + 1 ) = S ( a ) + 1\),

此时显然有\(9 k - 1 \equiv 0 \pmod{ 5 }\),\(k \equiv 4 \pmod{ 5 }\).\(n_{ \min } = 49999\).

Problem12

求满足以下条件的最大的正整数\(n\):十进制下每一位数字互不相同,且\(\forall m , 10^m \leq n , \lfloor \frac{ n }{ 10^m } \rfloor | n\).

Solution12

显然不可能是五位数及以上,而且如果是四位数的话最后一位必然是\(0\).

不妨设其为\(\overline{ ab }\),其中\(b = 10 c\),\(a\)\(b\)的因子,不妨枚举一下\(k = \frac{ b }{ a }\).注意到因为\(a\)中不能有\(0\),所以\(k \in \{ 2 , 4 , 5 , 8 \}\).取\(k = 2\)试出来\(3570\)是合法的,而且显然\(k \in \{ 4 , 5 , 8 \}\)的时候不可能有更大的答案了.

Problem20

\(a_1 = \sqrt{ 2 } , a_{ n + 1 } = \lfloor a_n \rfloor + \frac{ 1 }{ a_n - \lfloor a_n \rfloor }\),求\(\sum_{ k = 1 }^{ n } a_k , n = 2024\).

Solution20

这一看就是个环,设\(a_n = b_n + c_n \sqrt{ 2 }\).难点显然在下取整函数.

没想出太好的办法,选择使用数学归纳,注意到:

\[ \begin{cases} a_1 = 0 + \sqrt{ 2 } \\ a_2 = 2 + \sqrt{ 2 } \\ a_3 = 4 + \sqrt{ 2 } \\ \cdots \end{cases} \]

容易猜测\(b_n = 2 ( n - 1 ) , c_n = 1\).也就是\(a_n = 2 ( n - 1 ) + \sqrt{ 2 }\),数学归纳一下即可.

那么\(\sum_{ k = 1 }^n a_k = n ( n - 1 ) + n \sqrt{ 2 }\),带入\(n = 2024\)即可.

2022图选

Problem1

问能否将有限个单位正方形摆放在平面上使得:

  1. 任意两个正方形至多有一个顶点重合

  2. 每个正方形的每个顶点都与其他某个正方形的顶点重合

Solution1

这个题传到我这里题面已经丧失了,但反正理解起来就两种情况

  1. 边不能相交.此时不可能.考虑扫描线,从上到下扫一条线,然后第一次扫到的最右边的那个顶点显然不可能和其它的某个正方形顶点重合.

  2. 边可以相交,放到正十二边形的边上.

Problem2

\(\lfloor ( \frac{ 1 + \sqrt{ 5 } }{ 2 } )^{ 12 } \rfloor\).

Solution2

考虑\(( \frac{ 1 + \sqrt{ 5 } }{ 2 } )^3 = 2 + \sqrt{ 5 }\),\(\lfloor ( \frac{ 1 + \sqrt{ 5 } }{ 2 } )^{ 12 } \rfloor = 161 + \lfloor 72 \sqrt{ 5 } \rfloor = 321\).

也可以考虑类似斐波那契数列,取\(f_n = ( \frac{ 1 + \sqrt{ 5 } }{ 2 } )^{ n } + ( \frac{ 1 - \sqrt{ 5 } }{ 2 } )^{ n }\),其满足\(f_n = f_{ n - 1 } + f_{ n - 2 } , f_0 = 2 , f_1 = 1\),取\(f_{ 12 } - 1\)就是答案\(321\).

Problem3

对于一个加法乘法环,要求你利用:

  1. 乘法结合律、交换律、对加法的分配律、逆元.

  2. 加法结合律、逆元.

来证明加法的交换律.

Solution3

倒反天罡题.

注意到\(( a + 1 ) ( b + 1 ) = ( b + 1 ) ( a + 1 )\),所以\(a + b = b + a\).

Problem4

给你\(n\)个数集\(a_i\),其中\(| a_i | = i + 1\),要你选出\(n\)个两两不同的数字满足\(x_i \in a_i\),求最少方案数.

Solution4

考虑从小的往大了选,每次可能会删掉一个可选择的数字,所以是\(2^n\).

Problem5

Alice和Bob博弈.Alice先选一个数\(m\),然后Bob选一个数\(n ( n > m )\),并构造一个\(n\)个点的竞赛图.Alice如果能从中选出\(m\)个不同的点,满足不存在某个点\(x\)到这\(m\)个点都有出边,那么Alice赢,否则Bob赢.问是否有人存在必胜策略.

Solution5

一开始以为Alice肯定赢,结果被gank了.

其实Bob一定赢.为啥呢?考虑一对点合法的概率,应该是\(( 1 - \frac{ 1 }{ 2^m } )^{ n - 2 }\),因此期望为\(E = \binom{ n }{ m } ( 1 - \frac{ 1 }{ 2^m } )^{ n - 2 }\),只需\(n\)足够大的时候期望\(< 1\),则说明一定存在\(0\),也就是Bob总有必胜策略.

注意到只需证明\(\exists n\),\(\binom{ n }{ m } < ( \frac{ 2^m }{ 2^m - 1 } )^{ n - 2 }\),而\(\binom{ n }{ m } = \frac{ n^{ \underline{ m } } }{ m ! } < n^m\).下面证明\(\exists n , n^m < ( \frac{ 2^m }{ 2^m - 1 } )^{ n - 2 }\).

两边取\(\ln\),不妨假设\(n \geq 3\),有\(m \ln n < ( n - 2 ) \ln ( \frac{ 2^m }{ 2^m - 1 } ) , \frac{ m }{ \ln ( \frac{ 2^m }{ 2^m - 1 } ) } < \frac{ n - 2 }{ \ln n }\),\(\frac{ n - 2 }{ \ln n }\)显然在\(n \geq 3\)的时候单增,所以一定存在这么一个\(n\).

2023图选

Problem1

求单位正方形中能放下的最大的等边三角形的边长.

Solution1

首先肯定三角形有一个角卡在正方形的角上(不然可以平移过去),而且剩下两个角肯定卡在边上.

Problem2

求正整数拆分成有序的\(1 , 2\)序列的个数.

Solution2

显然为斐波那契数.

Problem3

定义\(*\)为集合\(G\)上的二元运算,已知:

  1. 满足结合律\(a ∗ b ∗ c = a ∗ ( b ∗ c )\).

  2. 存在左单位元\(e\),对任意\(a\)满足\(e ∗ a = a\).

  3. 对任意\(a\)存在左逆元\(b\),使\(b ∗ a = e\).

问:

  1. 左单位元是否也为右单位元.

  2. 左逆元是否也为右逆元.

Solution3

看(2),考虑设\(b\)\(a\)的左逆元,\(c\)\(b\)的左逆元,则\(cba = ce = a , ab = ceb = e\).

看(1),设\(b\)\(a\)的逆元,\(ea = aba = ae\),所以左单位元也是右单位元.

值得一提的是,这个题如果将条件(3)改为右逆元,则不一定构成群.

感性理解一下改前的题,如果存在左逆元的话,说明\(ab\)的时候\(b\)不能彻底损失信息,而观察\(ab = eab\)知道\(a\)也不能损失信息,于是应该是群.

但怎么构造反例呢?首先得造出来左单位元对吧.答案给了一种很聪明的构造方式:考虑运算\(( a_1 , b_1 ) ( a_2 , b_2 )\),想办法让其损失掉\(( a_1 , b_1 )\)中的信息(这样使其不存在左逆元,但可以构造出左幺元).注意到\(( a_1 , b_1 ) ( a_2 , b_2 ) = ( a_1 + a_2 , b_2 )\)即可,存在左幺元为\(( 0 , 0 )\),右逆元为\(( - a , 0 )\).

Problem4

\(f\)的定义域和值域都是正整数并且\(f ( xy ) = f ( x ) + f ( y ) - 1\),求:

  1. 是否存在这样的函数.

  2. 是否存在无数个这样的函数.

  3. 是否存在严格递增的函数.

Solution4

\(g ( x ) = f ( x ) - 1\),则\(g ( xy ) = g ( x ) + g ( y )\).

对于(1),取\(g ( x ) = 0 , f ( x ) = 1\)即可.

对于(2),考虑\(g ( p^k ) = kg ( p )\),只需要让\(g ( p )\)取不同的值即可.

对于(3),考虑\(g ( 2^a ) = ag ( 2 )\),\(g ( 3^b ) = bg ( 3 )\).

考虑构造\(a , b\),使得\(2^a < 3^b\)但是\(ag ( 2 ) \geq bg ( 3 )\).不妨取\(a = \lceil \frac{ bg ( 3 ) }{ g ( 2 ) } \rceil\),那么必定有:

$$ \[\begin{aligned} 2^{ \lceil \frac{ bg ( 3 ) }{ g ( 2 ) } \rceil } & < 3^b \\ \lceil \frac{ bg ( 3 ) }{ g ( 2 ) } \rceil & < b \log_2 3 \\ \frac{ bg ( 3 ) }{ g ( 2 ) } + \Delta & \leq b \log_2 3 \\ \end{aligned}\]

$$

于是如果存在,必定需要\(\frac{ g ( p_1 ) }{ g ( p_2 ) } \geq \log_{ p_2 } p_1 \land \frac{ g ( p_2 ) }{ g ( p_1 ) } \geq \log_{ p_1 } p_2\),也就是\(\frac{ g ( p_2 ) }{ g ( p_1 ) } = \log_{ p_1 } p_2\).但是左边是有理数右边是无理数,不可能.

Problem5

对于任意\(2 n - 1\)个正整数(可重复),问其中是否一定有\(n\)个数的和能被\(n\)整除,这题\(n = 50\).

Solution5

考虑当\(n\)是合数的时候,设\(n = pq\),则可以将其拆成\(q - 1\)组每组\(2 p\)个数以及一组\(2 p - 1\)个数,因此只需要这些都可以找到\(p\)个数使得其是\(p\)的倍数,组合起来就行了.

只需要解决\(n\)是质数的情况.

感觉场上的最优解应该是解决\(n = 2\)\(n = 5\)的情况然后拼成\(n = 50\).

\(n = 2\)的时候显然是对的.

这谁想得到啊?

考虑反证,如果不存在的话,显然\(S = \sum_{ } ( x_{ p_1 } + x_{ p_2 } + \cdots + x_{ p_n } )^{ p - 1 } \equiv \binom{ 2 n - 1 }{ n } \equiv 1 \pmod{ n }\).

但是考虑左边那个多项式的每一项,形如\(c \prod_{ i = 1 }^k x_{ p_i }^{ e_i }\).注意到\(c\)一定是\(\binom{ 2 n - 1 - k }{ n - k }\)的倍数,而后者\(\bmod n\)\(0\).

这玩意到底咋想到的?

不过其实也合理,因为\(1\)并不是对称的,而左边是个对称式子,某个\(x\)增大也无所谓,这意味着左边应该是为\(0\)的,我们要做的就是去证明它是\(0\).

2024图选

Problem1

问在双曲线\(xy = 1\)上有一个三个点都在上面的等边三角形,求其边长.

Solution1

不会做,取个特殊值知道答案应该是\([ 2 \sqrt{ 6 } , + \infty )\).

Problem2

我们称”能表示为两个数的平方和”的数是好的,求证:

  1. 如果\(n , m\)都是好的,那么\(nm\)是好的.

  2. \(2024\)不是好的.

Solution2

如果\(n = a^2 + b^2 , m = c^2 + d^2\),那么\(nm = a^2 c^2 + a^2 d^2 + b^2 c^2 + b^2 d^2 = ( ac - bd )^2 + ( ad + bc )^2\).

\(2024 = 2^3 \times 11 \times 23\),使用反证法,不妨设其可以被表示为\(a^2 + b^2\).

讨论一下:如果\(a , b\)均为奇数,那么\(a^2 + b^2 \equiv 2 \pmod{ 8 }\),不符题意.

于是\(a , b\)应该均为偶数,那么就有\(a '^2 + b '^2 = 506\).简单枚举一下就知道不存在.

当然这个题是个数竞结论,可以直接套用结论.

Problem3

对于集合\(G\),\(e \in G\),定义域为\(G\)的函数\(f\)满足以下性质:

  1. \(e \in G\),但\(e\)不在\(f\)的值域中.

  2. \(G\)关于\(f\)封闭.

  3. \(\exists A \subseteq G\),\(e \in A\)\(A\)\(f\)封闭,则\(A = G\).

\(G\)上定义二元运算\(\circ\),满足\(ae = a , af ( b ) = f ( ab )\).

求证:

  1. 存在幺元.

  2. 运算满足交换律.

  3. 运算满足结合律.

Solution3

只需要证明运算满足交换律即可.

考虑性质(3),我们不妨先往\(A\)里面扔个\(e\),此时\(A\)一定不满足条件.我们不断从\(A\)中选出一个元素\(w\)满足\(f ( w ) \notin A\),并把\(A : = A \cup \{ f ( w ) \}\).不断做这个过程显然最后会得到\(G\),这意味着任何一个元素\(a\)可以写成\(f ( f ( f \cdots f ( e ) ) )\)的形式.

不妨将\(f\)函数嵌套\(k\)次记作\(f^{ ( k ) }\),那么我们要证明的是\(a = f^{ ( A ) } ( e ) , b = f^{ ( B ) } ( e )\),\(ab = ba\).

考虑\(ab = f^{ ( A ) } ( e ) f^{ ( B ) } ( e ) = f^{ ( B ) } ( f^{ ( A ) } ( e ) e ) = f^{ ( A + B ) } ( e )\),因此证毕.

Problem4

给出一个具体函数满足:

  1. \(f ( x + y ) = f ( x ) + f ( y ) + xy\).

  2. \(f ( xy ) = f ( x ) f ( y ) + f ( x - 1 ) f ( y - 1 )\).

Solution4

先注意到\(f ( 0 ) = 0 , f ( 1 ) = 1\).

\(x\)为主元两边求导,立刻得到\(f ' ( x + y ) = f ' ( x ) + y\),因此\(f ' ( x )\)是斜率为\(1\)的一次函数,立刻得到\(f ( x ) = \frac{ x^2 }{ 2 } + \frac{ x }{ 2 }\).

Problem5

对于\(r = \sqrt{ 2 }\),是否存在正整数\(p\)和整数\(q\)满足\(| pr - q | < \frac{ 1 }{ 2024 }\)\(p < 2024\).

Solution5

考虑取\(0 , \sqrt{ 2 } , 2 \sqrt{ 2 } , 3 \sqrt{ 2 } , \cdots 2023 \sqrt{ 2 }\)的小数部分,记作\(a_0 , a_1 , \cdots a_{ 2023 }\).

由鸽笼原理,一定存在两个数\(0 \leq x < y \leq 2023\)满足\(| a_x - a_y | < \frac{ 1 }{ 2024 }\),于是证毕.

2019茶选

Problem1

在一个数轴上,你站在\(0\)点,并按照如下算法寻找\(x ( x > 0 )\)点处的牛:

1
2
3
4
5
6
7
curpos = 0;
curdir = LEFT;
step = 1;
while (没有找到牛) {
沿着 curdir 方向,走 step 单位距离,如果找到牛就停止;
如果没有找到牛,回到原点并将 curdir 设为反方向,step = step * 2;
}

大约至少需要多少步才能找到牛?

A. \(3 x\) B. \(5 x\) C. \(7 x\) D. \(9 x\) E. 以上答案都不对.

Solution1

考虑找到牛的时候\(step\)为多少,应该为\(2^{ 2 k }\),其中\(k\)满足\(2^{ 2 k } \geq x > 2^{ 2 ( k - 1 ) }\).此时走的步数应该是\(ans = 2 \sum_{ i = 0 }^{ 2 k - 1 } 2^i + x = 2^{ 2 k + 1 } - 1 + x\)步.而\(x \leq 2^{ 2 k } < 4 x\),所以\(ans < 9 x - 1\).

Problem2

给定\(10\)个实数变量\(x_1 , \cdots , x_{ 10 }\),满足它们均\(\geq 1\)且两两不同.你要寻找一组\(\{ x \}\)和一个实数\(a\),使得存在尽可能多组\(\langle b \rangle , b_i = \pm 1\),满足\(\sum_{ i = 1 }^{ 10 } b_i x_i \in ( a , a + 2 )\).

最多存在多少组\(\langle b \rangle\)?

A. \(512\) B. \(252\) C. \(504\) D. \(684\) E.以上答案都不对.

Solution2

不妨猜测\(x\)全取\(1\)最优,此时的答案是\(\binom{ 10 }{ 5 } = 252\).

能不能严格证明这个事情呢?我们不妨注意到一个事情:由于\(x \geq 1\),所以如果存在两组\(\langle b \rangle\),使得\(A\)组中选择取\(+ 1\)恰好是\(B\)组的子集,那么\(S_A \leq S_B - 2\),不可能同时满足条件.

如果我们能选出若干个互不相交的集合呢?那我们显然可以让\(x\)尽可能接近\(1\),这样就是满足条件的.所以问题变为对于一个大小为\(10\)的集合,要在其中挑选出尽可能多的子集使得这些集合两两之间没有包含关系,有结论说这个东西取\(\binom{ 10 }{ 5 }\)最优,即Sperner定理.其实也就是Dilworth定理的特例.

Problem3

给定无向图\(G = ( V , E )\),我们称一个图是好的,如果:

  1. 每个点的度数均为\(d\).

  2. 任何一个大小不超过\(\frac{ | V | }{ 2 }\)的联通集合\(S\),其邻居(不属于\(S\)但和\(S\)中的某个点存在直接相连的边)的大小\(\geq \frac{ 5 }{ 4 } | S |\).

求证:好的图中任意两个点\(u , v\)之间的最短路径长度\(dis ( u , v ) = O ( \log | V | )\).

Solution3

考虑以\(u\)为起点一点一点往外扩张,这样一直扩张到\(\frac{ | V | }{ 2 } + 1\)时,集合中每个点到\(u\)的距离不超过\(O ( \log | V | )\).

然后以\(v\)做同样的事,由于这两个集合大小之和大于\(| V |\),说明一定有交,且存在一条路径长度为\(O ( \log | V | )\)的路径,最短路径肯定比这个还短.

Problem4

给你两个完全相同的鸡蛋和一个\(n = 100\)层的高楼,你每次可以将鸡蛋从某一层楼掉下去.问你最少用多少次操作才能测出能让鸡蛋摔碎的最低楼层.

Solution4

经典信息论题.考虑构造一棵左倾的决策树,从根到任何一个叶子节点最多向右走两步,并且有\(101\)个叶子节点(因为还有可能从最高层掉下去不碎).

\(f_{ i , 1 / 2 }\)表示一棵有\(i\)个叶子的树,最多向右走\(1 / 2\)步,深度最低为多少.显然\(f_{ i , 1 } = i - 1\).

不妨设最后的最大深度为\(k\),需要满足\(1 + \sum_{ i = 1 }^k i = 1 + \frac{ k ( k + 1 ) }{ 2 } \geq 101 , k ( k + 1 ) \geq 200\),\(k_{ \min } = 14\).

Problem5

\(n\)个人要进行一场游戏.游戏设计者准备了\(n\)张卡片,正面分别写着\(n\)个人的名字,背面写了\([ 1 , n ]\)\(n\)个不同的数字.所有卡片都背面朝上放置在一个房间里.

当设计者准备完成后,\(n\)个人可以经过充分的讨论,并依次进入房间,一张一张地翻开\(\lfloor \frac{ n }{ 2 } \rfloor\)张卡片,并找到写有自己名字的卡片.当一个人操作结束后,他无法与其他人交流直到游戏结束.

只有所有\(n\)个人全部找到了写有自己名字的卡片,他们才能获胜.请问:是否存在一种策略,使得无论设计者怎样安排名字和数字的对应,他们均拥有超过\(0 . 1\)的胜率.

Solution5

这题真理元素讲过.做法是每个人先翻开自己编号的位置的卡片,假设卡片上数字是\(a\),如果\(a\)就是自己的编号就下班;反之接下来翻开\(a\)位置的卡片.为了防止设计者刻意安排,可以提前自己随机一个数字的映射.这样失败当且仅当场上存在一个长度大于\(\frac{ n }{ 2 }\)的环.

考虑总方案数是\(n !\).不妨枚举这个环的长度为\(K\),则存在一个长度\(= K > \frac{ n }{ 2 }\)的环的方案数是\(\binom{ n }{ K } ( K - 1 ) ! ( n - K ) ! = \frac{ n ! }{ K }\).所以此时的概率为\(\frac{ 1 }{ K }\).

那么失败的概率就是\(H_n - H_{ \frac{ n }{ 2 } } \approx \ln 2\).

2022茶选

Problem1

证明弱对偶定理,差不多就是:

提一个问题:最大化\(z = 5 x_1 + 8 x_2 + 4 x_3\),其中:

  1. \(x_1 , x_2 , x_3 \geq 0\)

  2. \(\frac{ 1 }{ 2 } x_1 + 5 x_2 + 9 x_3 \leq 3\)

  3. \(4 x_1 + 7 x_2 + 3 x_3 \leq 6\)

再提一个问题:最小化\(v = 3 y_1 + 6 y_2\),其中:

  1. \(y_1 , y_2 \geq 0\)

  2. \(\frac{ 1 }{ 2 } y_1 + 4 y_2 \geq 5\)

  3. \(5 y_1 + 7 y_2 \geq 8\)

  4. \(9 y_1 + 3 y_2 \geq 4\)

现在请你证明:\(z \leq v\).

Solution1

下面乘一下配一下上面的系数,自然得证.

写成矩阵形式,设\(X = \begin{bmatrix}x_1 & x_2 & x_3\end{bmatrix} , A = \begin{bmatrix}0 . 5 & 4 \\ 5 & 7 \\ 9 & 3\end{bmatrix} , Y = \begin{bmatrix}y_1 \\ y_2\end{bmatrix}\),不难发现\(z \leq XAY \leq v\).

Problem2

半径为\(R\)的球里放点,要求两两之间距离不能小于\(1\),证明至多放\(( 2 R + 1 )^3\)个.

Solution2

要求两两距离不能小于\(1\)等价于往其中放半径为\(0 . 5\)的球,这种球体积为\(\frac{ 4 }{ 3 } \pi \frac{ 1 }{ 8 }\).然后原球要扩大一圈,所以原球体积变为\(\frac{ 4 }{ 3 } \pi ( R + 0 . 5 )^3\).除一下得到答案.

Problem3

一个无限长的数轴上有一辆车,它的初始坐标是个未知的整数\(n\).

它每秒以\(v\)的速度行驶,其中\(v\)是个未知的整数(可以为负).

现在你每秒能进行一次这样的询问:询问整数\(x\),你会得知此时车的坐标是否是\(x\)(Yes or No).

请给出一个策略,使得在有限的时间里可以获得一次Yes回答.

Solution3

\(t\)秒的时候车应该在\(n + vt\)处.由于我们知道现在是第几秒,枚举\(n , v\)然后不断check即可.这个是经典的证明\(\mathbb{ Z }^2\)\(\mathbb{ N }\)等势.按照\(| n | + | v |\)排序然后一个一个遍历.

Problem4

对满足\(\forall i , | i - p_i | \leq 1\)的排列计数.

Solution4

简单题,设\(f_n\)为答案,考虑\(p_n\)取什么.

\(p_n = n\)时,方案数为\(f_{ n - 1 }\).

\(p_n = n - 1\)时,\(p_{ n - 1 } = n\),方案数为\(f_{ n - 2 }\).

于是,\(f_1 = 1 , f_2 = 2\),\(f_n = f_{ n - 1 } + f_{ n - 2 }\).

Problem5

你有一个\(n \times n\)的棋盘.初始所有格子都是白色的.

你可以选择\(k\)个格子染黑.此后,如果某个格子四联通的两个格子都是黑色,它自己也会变成黑色.

你要让所有格子最终都变黑.试证明:你一开始选择染黑的格子数\(k\)最小值是\(n\).

Solution5

数学归纳了半天,屁用没用.

注意到在扩张过程中,黑色格子的周长不会变大,所以至少是\(\frac{ 4 n }{ 4 } = n\)个.

Problem6

\(F = \{ S_1 , S_2 , S_3 , . . . , S_{ | F | } \}\),定义一个集合\(T\)能被\(F\) shattered为:\(T\)的任意一个子集(包括它自己和空集),都可以由\(T \cap S_{ i_1 } \cap S_{ i_2 } . . .\)表示.其中\(S_{ i_j }\)\(F\)中的集合(就是说每个子集都等于\(T\)和某些\(F\)内集合的交.)

定义一个\(F\)的”VC-Dimension”是,能被他shattered的集合\(T\)的大小的最大值.

\(F\)中的集合们只会包含某\(n\)种不同的元素.证明:

  1. 任意一个\(F\)能shattered的\(T\)至少有\(| F |\)个.

  2. 对于一个VC-Dimension的大小为\(k\)\(F\),其\(| F | \leq \sum_{ i = 0 }^k \binom{ n }{ i }\).

Solution6

显然只要证明了(1),那么(2)是显然的.

那么怎么证明(1)呢?考虑数学归纳.先考虑拎出所有的\(S\),满足\(S , S \cup \{ x \} \in F\),然后将这些\(S \cap \{ x \}\)拎出来,假设有\(t\)个,左边删去\(x\)后再进行数学归纳得到\(| F | - t\)个集合(由于拎出了所有满足上述条件的集合,不可能删出重复的集合),右边也有\(t\)个集合,在这\(t\)个集合添上\(x\)这个元素即可.

\(t = 0\)怎么办?我们自己造一组满足条件的就行了.每次加入一个集合:如果这个集合存在一个前面所有的集合都没有的元素,那么显然把这个元素拎出来就行了.又注意到如果一个元素全局都有的话,那么很废物对吧,我们把这个元素删掉继续做.此时不妨设新加入的集合为\(S\)(选取最大的那个集合为新加入的),我们在前面的集合中找到一个与\(S\)有交的集合\(T\),根据上面的预处理,此集合显然存在.选出一个\(x \in S \setminus T\),不妨设\(S = S ' \cup \{ x \}\),令\(T ' = S ' \cap T\),然后用\(T '\)代替原本的\(T\)即可.

2023茶选

Problem1

\(p ( x )\)表示\(x\)的最大质因子,求所有\(( x , y , z )\)使得:

  1. \(x < y < z\)\(x + z = 2 y\).

  2. \(p ( xyz ) \leq 3\).

Solution1

不妨令\(g = \gcd ( x , y , z )\),令\(x ' = \frac{ x }{ g }\),则只需要解:\(x ' + z ' = 2 y '\).

我们有\(y - x = z - y\),则\(\gcd ( y ' , x ' ) = \gcd ( y ' , y ' - x ' ) = \gcd ( y ' , z ' ) = 1\),用这个能解决不少讨论.

此时有以下两种情况:

  1. \(2 \nmid x ' , 2 \nmid z '\).

  2. \(2 \mid x ' , 2 \mid z ' , 2 \nmid y '\).

先看(1),设\(x ' = 3^a , z ' = 3^c , y ' = 2^b\).方程变为\(3^a ( 1 + 3^{ c - a } ) = 2^{ b + 1 }\),一定有\(a = 0\),只需解\(1 + 3^{ c } = 2^{ b + 1 }\).

\(b \leq 2\)的时候,经检验有\(\begin{cases}c = 0 \\ b = 0\end{cases}\)(舍)和\(\begin{cases}c = 1 \\ b = 1\end{cases}\)两组解.

\(b \geq 3\)的时候,注意到\(3^{ c } \equiv - 1 \pmod{ 4 }\),所以\(c\)是偶数.又注意到\(3^{ c } \equiv - 1 \pmod{ 8 }\),但是奇数的平方\(\bmod 8\)应该是\(1\),不符.

再看(2),设\(x ' = 2^d , z ' = 2^e , y ' = 3^b\).

\(e = 1\)时,显然不符.

\(d = 1 , e > 1\)时,要解\(2^{ e - 1 } + 1 = 3^{ b }\).当\(e = 2\)的时候有一组解\(\begin{cases}e = 2 \\ b = 1\end{cases}\).当\(e \geq 3\)的时候,有\(3^b \equiv 1 \pmod{ 4 }\),说明\(b\)是偶数.

那必然有\(2^{ e - 1 } = 3^b - 1 = ( 3^{ \frac{ b }{ 2 } } + 1 ) ( 3^{ \frac{ b }{ 2 } } - 1 )\).令\(t = 3^{ \frac{ b }{ 2 } } - 1\),则\(2^{ e - 1 } = t ( t + 2 )\).则要么\(t = 2\),要么\(t + 2 = 2\).解出\(b - 2\),此时有\(\begin{cases}e = 4 \\ b = 2\end{cases}\).

综上,解出来的解有\(\begin{cases}x ' = 2 \\ y ' = 3 \\ z ' = 4\end{cases} , \begin{cases}x ' = 1 \\ y ' = 2 \\ z ' = 3\end{cases} , \begin{cases}x ' = 2 \\ y ' = 9 \\ z ' = 16\end{cases}\).

但其实有更厉害一点的做法,考虑升幂引理.

先看方程\(2^x + 1 = 3^y\),考虑两边\(\bmod 3\)知道\(x\)是奇数,于是\(v_3 ( 2^x + 1 ) = v_3 ( 3 ) + v_3 ( x ) = y , 3^{ y - 1 } | x , x \geq 3^{ y - 1 }\),用这个放缩一下就行.

再看方程\(2^x = 3^y + 1\).仍然考虑两边\(\bmod 4\),知道\(y\)是奇数.\(x = v_2 ( 3^y + 1 ) = v_2 ( 3 + 1 ) = 2\),当场下班.

Problem2

给定两个随机分布:

\(x ∼ D_1\):从\({ 0 , 1 , … , p − 1 }\)中等概率随机一个\(y\),令\(x = y   \bmod  { 2^k }\).

\(x ∼ D_1\):从\({ 0 , 1 , … , 2^k - 1 }\)中等概率随机一个\(y\),令\(x = y\).

定义二者的统计距离为:\(SD ( D_1 , D_2 ) = \frac{ 1 }{ 2 } \sum_{ i = 0 }^{ 2^k - 1 } | P_{ D_1 } ( x = i ) - P_{ D_2 } ( x = i ) |\).

求证:\(SD ( D_1 , D_2 ) ≤ \frac{ 2^k }{ 4 p }\).

Solution2

\(w = p \bmod{ 2^k }\).则\(SD ( D_1 , D_2 ) = \frac{ w }{ 2 } ( P_{ D_1 } ( x = 0 ) - P_{ D_2 } ( x = 0 ) ) + \frac{ 2^k - w }{ 2 } ( P_{ D_2 } ( x = w ) - P_{ D_1 } ( x = w ) )\).

\(k = \lfloor \frac{ p }{ 2^k } \rfloor = \frac{ p - w }{ 2^k }\)不难发现\(P_{ D_1 } ( x = 0 ) = \frac{ k + 1 }{ p } , P_{ D_1 } ( x = w ) = \frac{ k }{ p }\).

\(SD ( D_1 , D_2 ) = \frac{ w }{ 2 } ( \frac{ p - w + 2^k }{ p 2^k } - \frac{ 1 }{ 2^k } ) + \frac{ 2^k - w }{ 2 } ( \frac{ 1 }{ 2^k } - \frac{ p - w }{ p 2^k } ) = \frac{ 1 }{ 2^{ k + 1 } } ( \frac{ w ( 2^k - w ) }{ p } + \frac{ w ( 2^k - w ) }{ p } ) = \frac{ w ( 2^k - w ) }{ p 2^k }\).

要证明\(\frac{ w ( 2^k - w ) }{ p 2^k } \leq \frac{ 2^k }{ 4 p } \Leftrightarrow w ( 2^k - w ) \leq ( 2^{ k - 1 } )^2\).由基本不等式显然.

Problem3

给你一个单增函数\(f\),满足定义域和值域都是\(\mathbb{ N }\),并且\(f ( f ( n ) ) = 3 n\),求\(f ( 2023 )\).

Solution3

首先我们不妨先试一下\(f ( f ( 1 ) ) = 3\).由于\(f ( 1 ) \geq 2\),且\(f ( 1 ) \ne 3\),所以\(f ( 1 ) = 2 , f ( 2 ) = 3\).

考虑\(f ( 3 n )\),必然存在一个\(n < m < 3 n\),使得\(f ( n ) = m , f ( m ) = 3 n\).

用这个找前几项,发现规律是把\(n\)写成三进制形式,如果首位是\(1\)就变成\(2\),首位是\(2\)就改为\(1\)再在后面加个\(0\).容易验证这是合法的\(f\)\(f ( 2023 ) = 3882\).

但问题没有解决,需要证明它是唯一的\(f\).

考虑数学归纳假设现在\(f ( x ) , x \in [ 1 , 3 k ]\)都确定了.

注意到如果\(f ( n ) = m , f ( m ) = 3 n , f ( 3 n ) = 3 m , f ( 3 m ) = 9 n\).所以如果\(f ( n ) = m\),我们实际上有\(f ( 3^k m ) = 3^{ k + 1 } n , f ( 3^k n ) = 3^k m\).数学归纳即可以证明\(f ( 3 k + 3 )\)一定是确定的.

接下来要证明\(f ( 3 k + 1 )\)\(f ( 3 k + 2 )\)一定是确定的.

手玩发现确定它们的方式有两种:

  1. \(f ( 3 k ) + 3 = f ( 3 k + 3 )\).

  2. \(\exists n , f ( n ) = 3 k + w ( w \in \{ 1 , 2 \} )\).

如果我们能说明至少可以取二者其一就行.

由归纳假设,不难发现当\(k\)在三进制下首位如果是\(2\),则一定满足(2).

\(k\)在三进制下首位是\(1\),则一定满足(1).

于是证毕.

Problem4

对于一个\(n \times n\)的包含\([ 1 , n^2 ]\)各一个的矩阵(下称为排列矩阵),定义一次操作为:将每行都任意重排;或将每列都任意重排.求证:

  1. 如果一个排列矩阵满足每行恰有模\(n\)\([ 0 , n - 1 ]\)的数各一个,则称它是好的.求证:好的矩阵可以通过两次操作变为一个满足第\(i\)行第\(j\)列为\(( i - 1 ) n + j\)的矩阵(不妨称为有序矩阵).

  2. 求证:任意排列矩阵可以通过一次操作变为好的.

Solution4

这题原题啊,AGC037D.

(1)显然,注意到有序矩阵的每列\(\bmod n\)不相同,可以先将每行按照\(\bmod n\)排序,再每列排序即可.

(2)的话我们考虑一次列操作.将\(\bmod n\)不同的数字分类,然后建一个二分图:左侧的点是数字分的类,右侧的点代表行,注意到这个东西是\(n\)正则二分图,根据Hall定理一定存在完美匹配.

Problem5

\(n ( \geq 2 )\)个硬币排成一个环.你被蒙上眼睛,你每次操作可以选择一个硬币的子集并将它们翻面.但是你每次操作之后,硬币的位置将会任意旋转(即变为原来的一个循环同构).如果你存在一种策略,使得对于任意初始局面和任意中途的旋转方案,有限步内一定可以令存在一个时刻所有硬币正面朝上,则称\(n\)是好的.求证:

  1. \(4\)是好的.

  2. 如果\(n\)是奇数,那么\(n\)不是好的.

  3. 求出所有好的\(n\).

Solution5

首先可以证明\(2\)是好的.

这么干:如果一开始都正面向上就赢了.不然第一步全翻,这样如果一开始是反面向上也赢了.下一次随便翻一个,再下一次全翻,这样四次中至少赢了一次.

从上面的观察可以发现啊,我们场上一定会进行若干次全局翻转操作,并且最后一次一定是一个全局翻转,不然我们每次只需要让一个位置保持不被翻到就输麻了.

转全局太复杂了,考虑转操作,问题转化为现在你要排若干个操作,使得它们任意旋转后,仍然可以保证前缀异或和取到了所有的情况.注意到不妨让第一轮轮空,此时最少需要\(2^n\)步.

不妨每进行一次非全局操作就全局翻一次,这样\(0\)\(1\)就没区别了.

先考虑全局异或和为偶数的时候:

注意到\(1100\)来一个\(1010\)之后啥也不变,但是\(1010\)来一个\(1010\)一定赢了.所以上来先来一个\(1010\),如果赢了就下班,没赢就来个\(1100\),这样\(1100\)要么下班,要么变成了\(1010\),再重复上面的操作.

如果全局异或和为奇数,那就随便异或一下,再按照偶数的做.

总的来说,先按照偶数的操作,不会改变全局异或和.如果没结束说明是奇数,变一下重复以上操作.

总结一下的话就是操作序列是:\(0000 , 1111 , 1010 , 1111 , 1100 , 1111 , 1010 , 1111 , 1000 , 1111 , 1010 , 1111 , 1100 , 1111 , 1010 , 1111\).

上面的构造启发我们手玩一下\(n = 3\),注意到此时的问题在于\(100\)\(110\),都很完蛋.

我们先考虑弱化版问题:就是我们摘下了眼罩,但是选择策略在旋转之前.如果这种情况我们都做不到那蒙上眼更做不到了对吧.

我们不妨将所有的状态分为两类:一类叫做成功状态,即如果一个状态是成功的,那它可以通过有限次操作得到全\(0\);另一类叫做失败状态,即只要初值是它,一定有一种旋转的方式使得一直得不到全\(0\).

我们来仔细看一下这两个状态应该是啥样的:

对于一个成功状态,应该有一个固定的选择翻面策略,使得它可以在有限次操作内达到另一个更接近全\(0\)的成功状态.我们不妨令一个成功状态的度为\(d\)表示它可以经过\(d\)步到达全\(0\),显然全\(1\)\(d = 1\),\(n = 4\)的时候,\(1010\)\(d = 2\),因为其可以通过一次操作转化为全\(1\),\(1100\)\(d = 3\),因为其可以用一次操作转化为\(1010\).

仔细思考上面的过程,也就意味着:任何一个成功状态的所有出边,必然要指向\(d\)比它更小的成功状态.

对于一个失败状态,应该有一个任意的选择旋转策略,使得它怎么翻都还是失败状态.

这个定义还是挺粗糙的,我们先看失败状态吧.

显然\(n = 3\)的时候,\(\{ 110 , 100 \}\)就是失败状态.

而对于\(n\)取任意来说,一定得存在一个\(d = 2\)的成功状态.一个显然的\(d = 2\)的成功状态要满足的条件是,假设它是\(a\),那么存在一个数\(b\),使得\(a \oplus b\)是全\(1\)或者全\(0\).既然\(a\)\(b\)旋转后只有两种结果,那么\(b\)的循环节必定为\(2\),也就是\(b\)一定要是\(101 \cdots 010\)这样的,于是\(n\)是奇数的时候一定不符合,这就证明了(2).

同理寻找\(d = 3\)的成功状态,现在我们已知的四种成功状态是\(111 \cdots 111\),\(000 \cdots 000\),\(101 \cdots 010\),\(010 \cdots 101\),所以考虑构造一个循环节长度为\(4\)的串,使得异或完它是这上面四种其一,注意到\(1100 \cdots 1100\)就是一个合法的串.

做到这里发现上面那个东西完全无法扩展啊.更要命的是我们现在还是睁着眼的,甚至没证明闭着眼是一样的.

找qyc讨论了一下得到了另一个思路的做法:

先证明\(n = 2^k\)一定是好的.考虑数学归纳,不妨这么干:构造一个长度为\(2^{ k - 1 }\)的串\(b\),使得其\(b_i = a_i \oplus a_{ i + 2^{ k - 1 } }\).然后由数学归纳,可以造出\(b\)\(0\)的情况.而如果\(b\)\(0\),则原串一定存在长为\(2^{ k - 1 }\)的循环节,并且消除循环节的过程不会改变\(b\)的值,仍然是数学归纳下去就做完了.

不然,设\(n = 2^k m\),

模仿上面的过程,不妨使用数学归纳证明其不成立.仍然是构造\(b\)数组,由于\(b\)数组都不可能全\(0\),显然也不可能成立.

这个能不能顺便证明\(n\)是奇数一定不行呢?还真可以.

考虑你现在要卡掉蒙眼的对手的构造,你选出一个位置来备用,剩下了\(n - 1\)个位置.

接下来无论对手怎么出,你都可以通过乱搞这个备用的位置,来保证前\(n - 1\)个位置的异或值为\(1\).因此对手一定不能完成任务.

2024茶选

Problem1

连续扔一枚硬币,连续扔出三个正面则停止.假设硬币扔出正面反面的概率都为\(50 \%\),求期望停止时间.

Solution1

简单题,设\(f_0 , f_1 , f_2 , f_3\),然后有\(\begin{cases}f_3 = 0 \\ f_2 = \frac{ 1 }{ 2 } f_3 + \frac{ 1 }{ 2 } f_0 + 1 \\ f_1 = \frac{ 1 }{ 2 } f_2 + \frac{ 1 }{ 2 } f_0 + 1 \\ f_0 = \frac{ 1 }{ 2 } f_1 + \frac{ 1 }{ 2 } f_0 + 1\end{cases}\),算出\(f_0 = 14\).

Problem2

Alice和Bob玩游戏,一共有三轮.每一轮中,Alice选择一个实数,Bob将这个数填到下式中任意一个框中.进行三轮后,如果下式方程有三个不同的整数解则Alice赢,反之Bob赢,求是否有必胜策略.

\[ x^3 + □ x^2 + □ x + □ = 0 \]

Solution2

纯粹的构造.

简单分析一下,不妨设三个解为\(- A , - B , - C\),方程应该可以写作\(( x + A ) ( x + B ) ( x + C ) = 0\).

拆开有\(x^3 + ( A + B + C ) x^2 + ( AB + AC + BC ) x + ABC = 0\).

这么对称,不妨猜一手Alice先选择\(0\),讨论一下:

  1. Bob令\(ABC = 0\).不妨令\(C = 0\).

此时方程变为\(x^2 + ( A + B ) x + AB = 0\).直接秒了,随便选一个数就行(比如选\(3\),如果Bob令\(AB = 3\),就再选\(4\);如果令\(A + B = 3\),就再选\(2\))

  1. Bob令\(A + B + C = 0 , C = - A - B\).

不妨令\(C ' = - C , D = AB\),则\(AB + AC + BC = D - C '^2 , ABC = DC '\).

接下来Alice要选择一个数字\(k\),如果Bob又令\(D - C '^2 = k\),发现在此时如果\(k\)是一个负的完全平方数,并且Alice接下来选择\(0\),当场就下班了.

所以不妨直接让\(k = - n^2\),然后看当\(DC ' = - n^2\)的时候如何去解.此时有\(AB ( A + B ) = n^2\).不难发现取勾股数就很优秀.

总结一下就是,Alice第二步选择\(- 3^2 \times 4^2 \times 5^2\),这样就赢了.

  1. Bob令\(AB + AC + BC = 0 , C = - \frac{ AB }{ A + B }\).

我是构造不出来了.但我可以抄答案,答案是你接下来选择\(6^2 \times 7^3\),两种情况如下:

\[ \begin{aligned} ( x + 2 \times 7 ) ( x - 3 \times 7 ) ( x - 6 \times 7 ) & = 0 \\ ( x - 2 \times 6^2 \times 7^2 ) ( x + 3 \times 6^2 \times 7^2 ) ( x + 6 \times 6^2 \times 7^2 ) & = 0 \end{aligned} \]

后来又找人讨论了一下这个是咋得出来的啊.考虑\(ABC \ne 0\),我们有的条件其实是\(\frac{ 1 }{ A } + \frac{ 1 }{ B } + \frac{ 1 }{ C } = 0\).方程现在是\(x^3 + ( A + B - \frac{ AB }{ A + B } ) x^2 - \frac{ A^2 B^2 }{ A + B } = 0\).不妨令\(a = A + B , b = AB\),方程实际上是\(x^3 + ( a - \frac{ b }{ a } ) x^2 - \frac{ b^2 }{ a } = 0\).最好能让\(a\)小一点,因此我们不妨直接取\(a = 1\),此时\(A = - n , B = n + 1 , C = n ( n + 1 )\),只要能构造这样的两组\(A , B , C\)使得它们的\(a_1 - \frac{ b_1 }{ a_1 } = - \frac{ b_2^2 }{ a_2 }\)即可.直接造看上去没啥前途,但是不难发现\(A = - nk , B = ( n + 1 ) k , C = n ( n + 1 ) k\)依然合法.此时有\(k_1 = a_1 , b_1 = - n ( n + 1 ) a_1^2 , k_2 = a_2 , b_2 = - n ( n + 1 ) a_2^2\),我们有\(a_1 ( n^2 + n + 1 ) = - n^2 ( n + 1 )^2 a_2^3\).取\(n = 2\)试试看!此时有\(7 a_1 = - 36 a_2^3\).取\(a_2 = 7 , a_1 = - 6^2 \times 7^2\),这就是上面那组答案的构造过程.

Problem3

人们之间可能会有讨厌的情况,讨厌关系是相互的.一个人最多讨厌另外\(3\)个人.现在希望将全部的人分成两组,使得每个人在自己的组内至多只讨厌\(1\)个人.这是一定可以办到的吗?

Solution3

考虑增广,对于一个不合法的点,它应当连了两个同色点.不妨将这个点反色,那么同色边的数量一定减少,因此一定存在操作终点.而只要当前不合法就一定可以继续操作,因此操作终点一定合法.

Problem4

有公式:

\[ \sum_{ S \subseteq \{ 1 , 2 , \cdots , n \} } ( P ( f ( R ) \oplus \bigoplus_{ i \in S } R_i = 0 ) - P ( f ( R ) \oplus \bigoplus_{ i \in S } R_i = 1 ) )^2 = 1 \]

其中\(f\)是任意一个将\(\{ 0 , 1 \}^n \rightarrow \{ 0 , 1 \}\)的函数,\(\oplus\)是二进制意义下的异或运算,\(R\)\(\{ 0 , 1 \}^n\)上的均匀分布,\(R_i\)表示第\(i\)位.再定义\(\chi_S ( r ) = \prod_{ i \in S } ( - 1 )^{ r_i }\).

按照下面的步骤证明上面的式子,也就是说,求证:

  1. \(\chi_S ( r ) \times \chi_S ( r ' ) = \chi_S ( r \oplus r ' )\).

  2. \(r \ne 0\)时,\(\sum_{ S \subseteq \{ 1 , \cdots , n \} } \chi_S ( r ) = 0\).

  3. \([ f ( r ) \oplus \bigoplus_{ i \in S } r_i = 0 ] - [ f ( r ) \oplus \bigoplus_{ i \in S } r_i = 1 ] = ( - 1 )^{ f ( r ) } \chi_S ( r )\).

  4. 证明原命题.

Solution4

(1)显然.

(2)也很经典,挑选一个\(j\),使得\(r_j = 1\),然后所有的集合分为两类:一类是包含\(j\),一类不包含,两类集合一一对应并且\(\chi\)互为相反数.

(3)显然.

来看(4),注意到\(P ( f ( R ) \oplus \bigoplus_{ i \in S } R_i = 0 ) = \frac{ 1 }{ 2^n } \sum_{ r } [ f ( r ) \oplus \bigoplus_{ i \in S } r_i = 0 ]\),而\(\sum_{ r } [ f ( r ) \oplus \bigoplus_{ i \in S } r_i = 0 ] - [ f ( r ) \oplus \bigoplus_{ i \in S } r_i = 1 ] = \sum_r ( - 1 )^{ f ( r ) } \chi_S ( r )\),要证明的只是\(\sum_{ S } \frac{ 1 }{ 4^n } ( \sum_r ( - 1 )^{ f ( r ) } \chi_S ( r ) )^2 = 1\),而:

\[ \begin{aligned} & \sum_{ S } ( \sum_r ( - 1 )^{ f ( r ) } \chi_S ( r ) )^2 \\ = & \sum_S \sum_{ r } \sum_{ r ' } ( - 1 )^{ f ( r ) + f ( r ' ) } \chi_S ( r \oplus r ' ) \\ = & \sum_{ r } \sum_{ r ' } ( - 1 )^{ f ( r ) + f ( r ' ) } \sum_S \chi_S ( r \oplus r ' ) \\ = & \sum_{ r } 2^n = 4^n \end{aligned} \]

于是证毕.

Problem5

Alice在手心上写了两个不同的实数.你可以看其中一只手上的,然后猜哪边的数大.设计一种策略使得不论两个数是什么,猜对的概率都严格大于\(50 \%\).

Solution5

我对这个题有亿点小疑问,但是先说策略.

随机(无需均匀)一个数\(x\),然后随机一只手,看上面的数字\(a\),如果\(a \geq x\)就认为\(a\)大,反之认为\(b\)大.只要随机到一个区间内的实数的概率不为\(0\)即可.

但是怎么随机实数呢?好像可以按照正态分布随机,我其实也不太懂.

Problem6

使用一些长方形的砖头搭墙.如果每块砖头都有至少一条边的长度是整数,且搭出的墙面是没有缝隙的长方形,求证:这个长方形也至少有一条边长是整数.

Solution6

这个题是经典知乎题,下面搬一下知乎上面整理的这个题的答案:

数论证明:令\(p\)为素数,把整个图形放大\(p\)倍(也就是长度\(1\)变成长度\(p\)).下面把每个交叉点\(( x , y )\)换成其整数部分\(( \lfloor x \rfloor , \lfloor y \rfloor )\),我们就得到了一个新的大矩形,它被划分为很多两边长均为整数的小矩形,而且每个小矩形有一边长能被\(p\)整除.这样这个新的大矩形的面积也能被\(p\)整除,所以它的有一边长能被\(p\)整除.这条边只是被换成了它长度的整数部分,所以变化不超过\(1\),所以在放大之前这条边的长度和某个整数相差不超过\(1 / p\).因为素数有无穷多个,所以原来的大矩形某一条边长度与某个整数相差无限小,证毕.

图论证明:令所有的交叉点为顶点.每个小矩形都有一边长为整数,我们把这两条边长为整数的边在图上标出(允许两顶点之间的重复边),另外两条边不连.这样除了大矩形的四个角以外每个顶点有\(2\)条边或者\(4\)条边(这是因为这个点,要么是处于一个丁字路口(两条边),要么是十字路口(四条边)),而大矩形四个角每个角只连了一条边.所以从大矩形一角开始存在一条欧拉路径在另一个角结束.因为图上连边的边长都是整数,把这个欧拉路径投影到大矩形的长宽,我们就得到了大矩形至少有一边长为整数.

组合证明:考虑Sperner引理(和染色有关的那个).假设结论不成立.把每个小矩形画上对角线,然后把所有交叉点\(( x , y )\)染色:如果\(x\)是整数,染X颜色.如果\(x\)不是整数但\(y\)是整数,染Y颜色.如果都不是整数,染Z颜色.由Sperner引理,三顶点被染不同颜色的三角形有奇数个(简单来说就是,你考虑大矩阵的左侧两个点都是X颜色,右侧一个是Y一个是Z,并且在最下面这条边(两个端点分别被染成了X颜色和Y颜色)上面只可能出现X和Y两种颜色,由于这两种颜色交替出现,那么连接不同颜色的边就会有奇数个,同理对于全局来说,三条边上连接不同颜色的边总共奇数个,内部的每一条边会在两个三角形中被各算一次,因此三个顶点染成不同颜色的三角形应该有奇数个),但由题目条件这种三角形不存在(如果一个点被染成了X颜色,那么上面的点如果存在也该被染成了X颜色,Y颜色同理,俩总会矛盾一个),矛盾.

扫描线证明:设大矩形为\([ 0 , a ] \times [ 0 , b ]\),并假设\(b\)不是整数.把所有小矩形的下边界去掉,然后令\(f ( t )\)为所有上边界\(y\)坐标不是整数,并且与直线\(y = t\)相交的小矩形的\(x\)方向边长之和.那么\(f ( 0 ) = 0\),而且当\(f ( t )\)变化的时候,它一定会变成另一个整数(原因在于一个小矩阵(假设已加入扫描线)上方的矩阵,如果想要退出扫描线,则必然横向长度是整数.同理对于一个没有加入扫描线的小矩阵上方的矩阵,如果想要加入扫描线,也需要横向长度是整数).所以\(f ( b )\)是整数.而因为\(b\)不是整数,\(f ( b )\)就是最靠上的所有小矩形的宽之和,等于\(a\),所以\(a\)是整数.

动态规划的设计

分析状态

Example1

给定一个序列,初始为空,进行多次操作,每次在序列末尾等概率加入一个\([ 1 , m ]\)中的数字,然后进行以下判断:

  1. 如果当前序列末尾两个数字相同且小于\(t\),假设都是\(x\),那就将它们都删去,加入一个\(x + 1\).

  2. 如果当前序列没有可以删的数字,并且序列长度为\(n\),终止操作.

给定\(n , m , t\),求最终序列的元素和的期望.

\(n , m \leq 10^3 , t \leq 10^9\).

首先\(t \leq 10^9\)显然是没用的,因为它最多也就能这么凑:\(m + n - 2 , m + n - 3 , \cdots , m , m\),合成一个\(m + n - 1\),因此我们令\(t = \min \{ t , m + n - 1 \}\)即可.

然后我们发现一个事实:如果这个序列某一个位置\(i\),有\(a_i < a_{ i + 1 }\),那么无论后面怎么做,这里的\(a_i\)都必不可能被删除.以此,我们不妨设\(f_{ i , j }\)表示序列长度为\(i\),序列开头元素为\(j\)的期望.然后发现中间的枚举巨大麻烦,完全不可以转移.

题解的思维顺序感觉很乱,于是我来马后炮一下重整一下顺序.

首先,我们的限制一共有两种:一个是数的大小不能超过\(t\),另一个是序列的长度不能超过\(n\).我们不妨设\(ans_{ n , t }\)表示在上述两种限制下的答案.接下来我们要做的,无非是开始分析转移\(ans\)需要求出哪些量,这些量又可以如何转移即可.

分析一下\(ans_{ n , t }\),考虑枚举一下开头元素是什么,那么第二个位置就不能是这个元素,然后后面再计算贡献,因此我们自然有\(ans_{ n , t } = \sum_{ x = 1 }^t E ( n 个 位 置 , 第 一 个 位 置 是 x 并 且 没 有 被 删 去 )\).

然后你就会发现这个问题真正难做的地方:我们这么顺着做,每次把第一个元素抠出去,但是这个元素是会影响后面的操作的!举个栗子:

如果插入的数是:\(3 , 3 , 3\),最终的答案应该是\(4 , 3\).

但如果我们一开始把第一个位置扣出去,就变成了\(3 , [ 3 , 3 ]\),最终的答案就变成了\(3 , 4\).也就是说,这里的动态规划问题在转移子问题的时候,需要前面的那个位置作为信息.不妨设\(g_{ i , j }\)表示当前后面还有\(i - 1\)个位置,当前前面已经放好了一个\(j\),这个\(j\)不能被删掉的期望,显然有\(ans_{ n , t } = \sum_{ x }^t g_{ n , x } P ( 最 终 序 列 中 , 这 里 是 k )\),问题只在于如何求\(g\).这个\(g_{ n , k }\)是钦定了这个位置放\(k\)的期望,后面我们需要将它乘上这个位置放\(k\)的概率才能得到真实的答案.这很合理,因为我们通常的一切概率与期望的递推通常都是有一个隐含的条件概率乘法的.

可能第一反应是,这个\(g_{ n , k } = ( k + \sum_{ j \ne k } g_{ n - 1 , j } )\).但是实际上这个是不对的.这里的\(k\)不能删掉不意味着后面的\(j\)不能删掉,事实上后面的\(j\)爱怎么删怎么删,只要不搞出一个\(k\)来就可以.因此我们需要设\(f_{ i , j }\)表示当前后面还有\(i\)个位置,第一个位置不能是\(j\),也不能曾经是\(j\)(因为这里只要是\(j\)都应该与前面合并),剩下的乱选的方案数.这个东西看上去它就不好转移,因为它限制太强了.我们正难则反!设\(f_{ i , j }\)表示后面还有\(i\)个位置,第一个位置现在或曾经是过\(j\)的期望.那么全集是什么呢?全集是\(ans_i\).

还没完啊,我们还需要求一下这里是\(k\)的概率,由于还有一个类似的\(f\),我们还要求一下这里曾经是\(k\)的概率.设前者为\(q_{ i , k }\),后者为\(p_{ i , k }\).我们来强调一下这里设计的原则:这里的\(p\)其实还蛮奇怪的,因为它设计的是:只要我当前在队首拿到了\(k\),我立刻停止后面的操作.这很好理解,因为后面无论怎么玩,这里都曾出现过\(k\)了.但是这个理解方式可以帮助我们写出下面的转移方程.

对于前者,我们发现这里是\(k\)等价于这里是\(k\)并且后面没有出现过\(k\),也就是\(q_{ i , k } = p_{ i , k } ( 1 - p_{ i - 1 , k } \times [ k < t ] )\).这里加一个限制是因为有不能超过\(t\)的限制.

对于后者,这里的\(k\)有很多种可能出现过,一种是直接加入,一种是合并而来,于是\(p_{ i , k } = \frac{ 1 }{ m } [ k \leq m ] + p_{ i , k - 1 } p_{ i - 1 , k - 1 }\).

因此我们几经辗转,终于得到了\(g\)的转移式子:

\[ q_{ i , k } g_{ n , k } = p_{ i , k } ( k + ans_{ i - 1 } - f_{ i - 1 , k } p_{ i - 1 , k } ) \]

就差\(f\)了.\(f\)有两种可能:要么最后仍然是\(k\),要么这个\(k\)已经被杀掉了.于是:

\[ p_{ i , k } f_{ i , k } = q_{ i , k } g_{ i , k } + ( p_{ i , k } - q_{ i , k } ) f_{ i , k + 1 } \]

Example2(CF1007E)

首先我们需要发现一个很强的性质:作用到了第\(i\)个站台就会清空前面所有站台.清空后就和\(a_i\)无关了,而如果还没涉及到一定和\(a_i\)有关,那么涉及到了一半怎么办呢?我们考虑这里涉及到了一半,那么前面一定被清空了,我们根据前面的清空情况现场计算这里的答案.

这启发我们:我们可以对这个做文章,我们设\(f_{ i , j }\)表示只考虑前\(i\)个站台,要撑\(j\)个单位时间需要的最少火车数量.\(g_{ i , j }\)表示只考虑前\(i\)个站台,要撑\(j\)个单位时间,并且\([ 1 , i - 1 ]\)全部清空需要的最少火车数.另外,这两个dp数组都要求不能有火车漏到后面,也就是火车不能坐上后面的人,不然设为\(+ \infty\)表示无法满足(对于全局,我们在\(n + 1\)处放一个\(a = + \infty , b = 0 , c = + \infty\)来保证一定会满载).为什么需要\(g\)作为辅助dp数组呢?我们先对着\(f\)分析.

考虑\(f_{ i , j }\)的转移,根据上面的分析,我们有两种可能:

第一种,前\(j\)轮中根本没接走站台\(i\)的人.此时需要满足\(f_{ i - 1 , j } \ne + \infty \land a_i + j \times b_i \leq c_i\).那么这里怎么更新\(g\)呢?设\(L = sa_{ i - 1 } + sb_{ i - 1 } \times j\),显然\(g_{ i , j } = \lceil \frac{ L }{ K } \rceil\),并且需要保证此时没有用到\(i\)以后的站台,因此需要保证\(\lceil \frac{ L }{ K } \rceil K \leq sa_{ i } + sb_i \times j\).注意到由于这里保证了\(f_{ i - 1 , j }\)是可以取到的,因此我们可以撑到第\(j\)秒,剩下的火车在\(j + \varepsilon\)秒全选.

第二种,前\(j\)轮中有火车接走站台\(i\)的人.设最后一次是在\(r\)时间接走的站台\(i\),那么此时必然清空了\([ 1 , i - 1 ]\),这里用了\(g_{ i , r }\).然后为了防止这里在\([ r + 1 , j ]\)这段时间中爆掉,因此还需要\(w = \lceil \frac{ \max \{ 0 , rem + ( j - r ) b_i - c_i \} }{ K } \rceil\),其中\(rem\)\(r\)时刻\(i\)剩下的人数.这些火车都要在\(r\)时刻之前解决(因为我们设了最后一次在\(r\)时间接走),不难发现我们其实不在乎前面具体怎么解决的,而只要在\(r\)这里保证没出问题就行.另外还要保证这个过程没有走到后面,也就有\(wK \leq rem\).但是,接下来在\([ r + 1 , j ]\)时刻就只需要对前面做操作,不过和一开始不一样的是,此时被清空了,因此我们设\(f_{ i , j , 0 }\)表示只考虑前\(i\)个站台,要撑\(j\)个单位时间需要的最少火车数量,但是\([ 1 , i ]\)都被清空为\(0\)过.

每一步看上去都很合理,但是如何想到可以这么dp的呢?说到底,dp是解决一个最优子问题的,我们发现我们知道时间,以及前面是否清空,就可以得知目前的状态.另外,由于我们是枚举目前的状态,因此中间的转移过程是易知的.

这个题的启发性大概有以下几点:

  1. 设计状态的时候,只考虑记录经过的时间/前面的初始值/目前考虑到第几位,由上面三点可以还原出所有状态.

  2. 由于我们确定了当前考虑到了第几位,我们就可以进行递推:原因很简单,只要我们考虑到某一位,就一定会影响前面所有的位置(全部清空以至于到达这里).一开始我犯了一个错是将\(g_{ 1 , t , 0 / 1 }\)全部设为\(0\),因为我觉得无论如何\(0\)位置都是清空的,但实际上这是错误的!因为在\(t\)时刻的\(1\)位置不一定合法.这就是这个设计巧妙的地方:它时刻保证了前\(i\)个的合法性,并且如果我们想要让\(i\)位置合法,一定要求让\([ 1 , i - 1 ]\)合法.

  3. 转移的时候,由于钦定了某一时刻是否选,因此我们可以直接算出从\(r \rightarrow t\)这个过程中会积累的量,这些量必然要在\(r\)时刻清理掉.由于钦定导致限制加强,因此这里就容易处理了.

可删除dp

Example1

定义一个有根树为大菊花,当且仅当这棵树的根的度数\(\leq m \land \nexists x \ne root , \deg ( x ) > 2\).对于每一条边,求将这条边连接的两个点合并后,以新点为根的大菊花数量.\(( n \leq 5 \times 10^5 , m \leq 50 )\)

注意到以一个点为根的大菊花数量是一个关于树的大小的背包合并.这样通过前缀后缀做到\(O ( nm^2 )\).

注意到这个背包是可删除的,所以就能做到\(O ( nm )\).

dp分界点

Example1(2022zrtg十连测day7 Permutation)

首先注意到\([ 3 , n ]\)一定会被分成两段递减的序列,分别跟在\(1\)\(2\)的后面,假设\(1\)\(2\)前面,这样算出答案后乘以\(n\)即可.

注意到\(i + 1\)一定可以放到\(i\)的前面,设\(f_i\)表示在\(i\)\(i + 1\)之间有分界点,这两个点后面分界合法的方案数.每次可以枚举下一个合法的分界点,不难发现这个分界点也即\(i\)的倍数\(\pm 1\)之类的,于是可以实现,复杂度\(O ( n \ln n )\).

基于贪心的dp

Example1(CF1666E)

先想一下别的东西怎么求.

如果我们要求最大值最小或者最小值最大怎么办?我们可以二分后贪心,而显然它们的差就是一个答案的下界,问题在于这个下界是否可以取到.

我们冷静一下,发现在可能的方案中,第\(i\)条线段的右端点的位置一定是一段连续的区间.

\(f_i\)表示第\(i\)个分界点可能的最小值,\(g_i\)表示第\(i\)个分界点可能的最大值.假设我们目前二分的最大值要小于等于\(mx\),最小值要大于等于\(mn\),那么我们有转移:

$$ \[\begin{aligned} f_{ i + 1 } & = \max \{ a_{ i + 1 } , f_i + mn \} \\ g_{ i + 1 } & = \min \{ a_{ i + 2 } , g_i + mx \} \\ \end{aligned}\]

$$

注意到\(f\)\(g\)的转移是无关的,而显然对于第\(i\)个分界点,它可以取\([ f_i , g_i ]\)中一个数,一定存在一个取法使得答案能取到下界.

为啥呢?只需让\(ans_{ i }\)表示第\(i\)条分界线是啥,那么我们\(ans_i\)是可以取\([ ans_{ i + 1 } - mx , ans_{ i + 1 } - mn ]\)中的任何一个数字的,我们将其和上面求出的\([ f_i , g_i ]\)求一下交集.如果交集为空,说明要么\(ans_{ i + 1 } - mn < f_i , f_{ i + 1 } < ans_{ i + 1 } < f_i + mn\),这是不可能的.另一种情况同理不可能,这就保证了一定可以取到答案.一定能使极差\(\leq mx - mn\).

数位dp

Example1([2022qbxt国庆Day3]string)

首先设\(f_{ i , j }\)表示长度为\(i\)的,以\(S [ n - j + 1 . . . n ]\)为子序列的字符串个数.

考虑按位处理,每次将\(T\)的一个后缀设为极大,然后不断地向前扩展这个后缀的长度,直到所到的位置再改为极大就会超出\(k\).这个时候我们停止更改,并且继续倒着修改,仍然修改每位,直到最后所积累的总数恰好为\(k\).

当然,做的时候一定要时刻铭记后面的部分设为的是极大字符串还是极小字符串,这里设为极大是简单的,因为可以直接继承上一位的枚举.

考虑这个过程,我们每将一个位置的值设为更大,相当于松弛了后面的所有序列,因此也就是一个数位dp.

Example2([CF1194G])

第一反应就是枚举\(x '\)\(y '\),然后用数位dp枚举\(d\)使得\(x = dx ' , y = dy '\).

但是有一个问题在于如果\(\gcd ( x ' , y ' ) \ne 1\)怎么办,这样有可能会算重.我们发现我们只判断\(\gcd ( x ' , y ' ) = 1\)的情况就行,然后写一个\(2^8\)判断\(x ' , 2 x ' , 3 x ' , 4 x '\)以及对应的\(y '\)出现了没有.复杂度\(( 9^4 \times 2^8 \times \log_{ 10 } n )\),有点难过.

但是我们发现这个\(2^8\)可能大了点,注意到只要出现一个我们就不用再记了,因此唯一需要记的是一对都没出现过的情况,这里只有\(3^4 \times 2\)的状态量,就可以快一点.

树形dp

Example1([JLoi2016]侦察守卫)

首先第一反应是记录子树内到子树根节点的最远的未被覆盖的点和最近的监测站,但是这样是\(O ( nd^2 )\)的复杂度.冷静一下,发现这两个一定只会有一个值有意义,这样就是\(O ( nd )\)的了.

写的时候犯了个很蠢的错:树形dp由于需要合并,所以如果有多步转移,一定要先把所有dp值都会进行的dp转移写成赋值转移,把其它的写成取\(\min\)转移.

轮廓线dp(插头dp)

Example1

现在有一个\([ 1 , n ]\)的排列,现在要从中选出一个集合\(S\),满足\(\forall x \in S , 2 x \notin S , 3 x \notin S\),求方案数.

首先考虑将每个数分解为\(a \times 2^b \times 3^c\)的形式,显然\(a\)不相同的数之间互不干扰.

对于\(a\)相同的一群数,我们考虑将\(( b , c )\)作为它在矩阵上的位置,不难发现上面的要求其实也就是选一个数就不能选它右边的数和下边的数,可以使用轮廓线dp转移.

高斯消元处理后效性

Example1

\(n\)个点的树,一开始位于一号点,每个点有一个颜色(\(0\)\(1\)),每次随机选择一个点\(v\),从当前所在点移动到\(v\)并将\(v\)的颜色取反(不是将这条路径上的颜色取反),当整棵树颜色相同时停止,求期望移动距离(每条边的长度为\(1\),当然不为\(1\)也能做).

\(n \leq 100000\).

首先我们发现这个树形结构很难搞,怎么办呢?

我会弱化问题!先考虑期望进行多少轮.

不难发现这个问题下,这个树没有任何意义,我们只需要看当前选中的点是\(1\)还是\(0\)就可以.不妨设\(f_{ i }\)表示当前有\(i\)个点是\(1\),最后全\(1\)或者全\(0\)所需要的期望步数,显然\(f_0 = f_n = 0\),\(f_{ i } = \frac{ 1 }{ 2 } ( f_{ i + 1 } + f_{ i - 1 } ) + 1\).欸,这不luoguP7099嘛.看来这个思路很对啊!

但是其实寄了,这个东西怎么想都很难拓展.一开始还想过计算每条边对期望的贡献,但也很难搞.

正确的做法是什么呢?正确的做法是我们统计每个点的贡献!你可能会很好奇这个点能有什么贡献,事实上,假设我们当前在\(u\),只要当前没有结束,我们还要选点\(v\),对答案的期望的贡献就是\(u\)到这棵树上所有点的距离之和除以\(n\),而这是一个定值.也就是说,只要我们统计一下到了每个点\(u\)多少次(要求不是最后一次),我们就可以全部加一加乘一乘得到答案.我们脱离了树的结构!

我们设\(f_{ i , j , 0 / 1 }\)表示当前场面上有\(i\)\(1\),\(j\)号点这里是\(0\)还是\(1\),它在结束前能被期望选多少次,注意\(f_{ n / 0 , j , 0 / 1 } = 0\).但是这个转移显然有点垃圾,我们再冷静一下:似乎我们不在乎每个点具体编号,只在乎它当前的颜色,于是我们可以设\(f_{ i , 0 / 1 }\)表示当前有\(i\)\(1\),\(0 / 1\)染色的点在接下来的操作中期望选择多少次.

我们可以写出以下转移:

\[ \begin{aligned} f_{ 0 / n , 0 / 1 } & = 0 \\ f_{ i , 0 } & = \frac{ i }{ n } f_{ i - 1 , 0 } + \frac{ n - i - 1 }{ n } f_{ i + 1 , 0 } + \frac{ 1 }{ n } ( f_{ i + 1 , 1 } + [ i + 1 \ne n ] ) \\ f_{ i , 1 } & = \frac{ i - 1 }{ n } f_{ i - 1 , 1 } + \frac{ n - i }{ n } f_{ i + 1 , 1 } + \frac{ 1 }{ n } ( f_{ i - 1 , 0 } + [ i - 1 \ne 0 ] ) \end{aligned} \]

为啥最后加上了\([ i + 1 \ne n ]\)呢?因为我们统计的是在没结束的情况下的答案.

乍一看这个转移成环并且极其复杂,可能需要高斯消元,但实际上不用,我们冷静观察一下:

我们假设我们已经求出了\(f_{ i , 0 / 1 }\)\(f_{ i - 1 , 0 / 1 }\),我们发现我们可以用这两个方程求出\(f_{ i + 1 , 0 / 1 }\),然后就比较典了:我们将所有的函数表示成\(af_{ 1 , 0 } + bf_{ 1 , 1 } + c\)的形式(之所以这么表示,是因为我们架设了\(f_{ 1 , 0 / 1 }\)已经求出来了,虽然实际上没求出来),而由于我们有右边界,我们可以用它表示出\(f_{ n , 0 / 1 }\),而\(f_{ n , 0 / 1 }\)我们已知,这样就可以解一个二元一次方程组.

最短路处理后效性

Example1([2022qbxt国庆Day2]operation)

首先注意到,\(a_i = 1\)的时候和\(a_i \ne 1\)的时候其实没有太大区别,我们在操作完后也需要用各种方式抵消影响.我们设\(f_i\)\(a_i = 1\),而其他\(a\)全都为\(0\)时的答案,不难发现最后的答案也就是\(\sum{ a_i f_i }\).

而上面的转移自然是:\(f_i = \min \{ b_i , w + \sum_{ j = l }^r f_j \}\).

但是,这个转移是有后效性的,不能直接进行dp,不过我们考虑用类似最短路的操作来处理.

换句话说,由于每次\(f_i\)最小的点不可能再被更新到,我们就把它设为已更新的点.当一个区间中的所有点都被标记为已更新后,我们就拿这个区间去更新别的点.

我们把每个线段挂到线段树上的节点,当我们把一个点标记为已更新,也就是检查这个点对应的线段树上叶子节点到根的路径上所有的线段树节点对应的区间是否全更新.均摊下来,一个区间只会被检查\(\log n\)次,这样就做完了.

组合意义

Example1([NOI2009] 管道取珠)

考虑组合意义,\(\sum a_i^2\)的意义也即满足操作序列\(u\)和操作序列\(v\)的最终结果相同的二元组\(( u , v )\)的数量.

不妨设\(dp_{ i , j , k }\)为第一个装置上方已经动了\(i\)个珠子,下放动了\(j\)个珠子,第二个装置上方动了\(k\)个珠子,下方动了\(i + j - k\)个珠子,并且两个装置截至目前的操作序列完全一样的方案数.显然\(dp_{ n , m , n }\)即答案.

Example2

求长度为\(n\)的排列的\(( \sum_{ i = 2 }^{ n - 1 } [ a_i < a_{ i - 1 } \And a_i < a_{ i + 1 } ] )^k\)的期望\(( n \leq 10^9 , k \leq 500 )\).

\(O ( n^2 k^2 )\)是显然的,枚举最小值在哪就行.

注意到我们要求的是\(\sum ans^k\),而加入\(1\)的时候,对于每个长度为\(n - 1\)的排列,有\(( n - 2 - 2 ans )\)个位置加入后会使答案加一,那我们要求的也就是:

\[ \sum ( n - 1 - 2 ans ) ( ans + 1 )^k + \sum ( 2 ans + 2 ) ans^k \]

推一推式子就可以做到\(O ( nk^2 )\),然后上拉格朗日插值就做完了.

等一下,这是noip模拟赛啊,哪来的拉格朗日插值?

注意到我们可以考虑组合意义,\(ans^k\)等价于从所有的地方中可重复地选出\(k\)个位置,如果随便选肯定可以钦定,问题在于可能会选出两个间隔为\(1\)的位置,这就比较麻烦了.所以我们不妨直接把所有被选中的位置求出来,能合并成一段波动序列的合并.这样,我们设\(f_{ i , j }\)表示已经选了\(i\)段波动序列,其中有\(j\)个谷的方案数.最后这些谷每个至少被选中一次,做一个辅助数组维护波动序列的数量即可,复杂度\(O ( k^3 )\).

二项式定理展开

Example1

\(\sum_{ i = 1 }^n \sum_{ j = 1 }^n ( a_i \oplus a_j )^2\),\(n \leq 10^5\),\(a_i \leq 10^9\).

考虑设\(f_i\)表示只考虑前\(i\)低的位置,高位全部默认为\(0\)的方案数.如果我们设\(cnt_i\)表示\(a\)中第\(i\)位为\(1\)的数个数,那根据\(( a + b )^2 = a^2 + 2 ab + b^2\),我们只需要求出\(g_{ i }\)表示只考虑前\(i\)低的位置,第\(i + 1\)位是\(1\)的数和第\(i + 1\)位是\(0\)的数两两异或之和,显然有\(f_i = f_{ i - 1 } + 2 cnt_i \times 2^i \times g_{ i - 1 } + cnt_i 2^{ i + 1 }\).

\(g\)可以用\(O ( n \log a )\)的复杂度求,这样总复杂度\(O ( n \log^2 a )\).

线头dp

Example1([20zr普及组五连测day1]区间)

\(dp_{ i , j , k }\)表示目前倒到第\(i\)个水杯,前面还有\(j\)个延续过来的未结束的线头,目前已经选定了\(k\)个人,转移的话需要枚举当前有几个人在此开始以及有多少人在此结束,这样是\(O ( n^5 )\)的复杂度,不太能接受.但不妨考虑先将有几个人在此开始以及前面的继承处理到目前的数组中,然后再选择若干个人结束,这样分开了两个过程,于是实现了\(O ( n^4 )\)的复杂度.

Example2([2022qbxt国庆Day6]rps)

首先三次询问的做法没区别,我们只考虑r的情况.

注意到我们肯定是想拿s去把p杀掉,不然p就会把r杀掉.考虑一个线头dp,设\(dp_{ i , 0 / 1 / 2 }\)表示前\(i\)个数,0:无接头;1:有接头无线头;2:有线头的情况.这样一个线头每延申就会使答案减少,而如果我们把一个?改为s也会使答案减少,大概做一做.

Example3([COCI2020-2021#2] Svjetlo)

首先发现,我们得到的序列不可能首尾相同,不然我们可以同时去掉开头和结尾.

然后发现,如果一棵子树内的点全部被点亮,这棵子树可以直接删去.这一步是必须做的,不然会多一步讨论.

我们设\(dp_{ u , 0 / 1 , 1 / 2 }\)\(u\)的状态为\(0 / 1\),以\(u\)为根的子树内有\(1 / 2\)个线头的方案数.注意如果子树内有\(0 / 2\)个线头,那么会在\(u\)处存在两个接头;不然则会只存在一个接头.

通过不断将下方的点合并到当前子树的根节点上,我们可以完成整个过程.

注意到两个接头如果在相邻的两个节点就可以自动接起来,因此\(dp_{ u , s , 2 }\)的两个接头实际上一个位于\(u\),另一个位于\(u\)的随便一个儿子.

换句话说,做线头dp的时候一定要注意,线头的相接是自然的过程(即两个线头相邻就会相接)还是需要手动接起来的过程.

Example4(CF626F)

先按照权值排序,一个人可以选择新建一个组,加入一个组,加入一个组并删除这个组

\(dp_{ i , j , k }\)表示目前走到\(i\),前面分成\(j\)组,总贡献不超过\(k\)的方案数.做的过程中是一个线头dp,每次每组的贡献都要加上当前位置和前面位置的差值.

Example5([XVII Open Cup named after E.V. Pankratiev. Grand Prix of Japan(openstrain contest 1489) J]Travel in Sugar Country)

一条线段上有\(n ( \leq 100 )\)个商店,要从中选出\(k ( \leq 10 )\)个不同的商店\(s_1 , s_2 , \cdots , s_k\),使得按顺序遍历这\(k\)个商店的路径长度是\(m ( \leq 30 )\)的倍数,求方案数.

这种来回走的也是一种线头dp的形式.

我们设\(dp_{ i , j , w , l }\)表示目前在判断了\(i\)个商店,选了\(j\)个,并且目前整个图有\(w\)条”路径”(连续走动),走过的路在\(\bmod m\)一意义下为\(l\)的方案数.最后的答案就是\(dp_{ n , k , 1 , 0 }\).

首先,我们对每个点求出\(D ( 1 , x )\),然后\(D ( x , y ) = | D ( 1 , y ) - D ( 1 , x ) |\),不难发现\(x\)越大\(D ( 1 , x )\)越大(不考虑取膜的问题),因此如果我们按照从左到右的顺序逐渐往里加入,那么我们就需要讨论这个新加入的点它的左右点的\(D\)和它的大小关系,也就是它左右点的加入时间,这显然可以使用线头dp实现.

我们先枚举一下起点和终点并将它们扔到图上,这样初始图上有一条路径(\(s_1 \rightarrow s_1\)),接下来,我们每插入一个点\(x\),我们考虑它的贡献:

  1. 新建一条路径,此时这个点的左右端点必然都是在他后面加入,它对总长度的贡献是\(- 2 D ( 1 , x )\),对方案数的贡献为\(1\).

  2. 插入到原来一条路径的开头/结尾.此时这个点有一个端点是比它早的,有一个会比它晚,对总长度的贡献为\(0\).

  3. 作为中心点合并两条路径,此时对总长度的贡献为\(2 D ( 1 , x )\).

这样我们就做到了\(O ( n^4 km )\)的复杂度.如果我们加两维\(0 / 1\)表示目前起点和终点是否加入,就可以把复杂度优化到\(O ( n^2 km )\).

相对顺序不变

如果遇到一些会不断改变当前状态的题目,有时可以考虑改变前后的一些元素的相对顺序是否改变.以及如果有两个物体相遇后交换位置的题目,如果物体本质相同,同样可以考虑直接穿过而不是交换.

Example1([bzoj4621]Tc605)

注意到最终的序列一定是由若干个数字段组成,而数字段的顺序也即原本序列的顺序,于是此题显然.

拆分区间

有的时候,注意到一个区间可以通过某些方式拆分成两个区间(断点可能是需要枚举的,也可能是固定的),从而可以递归处理/区间dp.

Example1([22zr提高组十连测day4]零二)

先考虑数字两两不同的时候怎么做,我们先找到\(A\)中的全局最大值所在位置和\(B\)中的全局最大值所在的位置.由于从堆中取出全局最大值后,堆一定成为了空堆.因此我们注意到此时\(A\)取出的数量和\(B\)的长度一定是相等的.

进一步考虑,这意味着一个全局最大值将把\(B\)序列分成两部分,这两部分将由\(A\)中相等的两部分分别生成.不妨假设这个全局最大值的位置是\(x\),那么对于\([ 1 , x ]\)这一段的\(A\)生成的\(B\)数组,它的最大值一定在末尾位置,而前面任意,显然它的数量等价于直接删掉最大值后的\(A\)能生成的\(B\)的数量.对于\([ 1 , x + 1 ]\)则任意.

那么我们所需要做的就是求出\(A\)的某一段删掉若干次最大值后的序列所能生成的\(B\)的数量.不妨设\(dp_{ l , r , i }\)表示\([ l , r ]\)中所有\(\leq i\)的数字组成的序列所能生成的数量.

如果\([ l , r ]\)这段区间中没有数字\(i\),那显然\(dp_{ l , r , i } = dp_{ l , r , i - 1 }\),不然,我们可以枚举两端分开的位置,那这个位置一定在数字\(i\)的后面.于是可以转移.

至于可能出现相同数字的情况,我们只需要把每个数字的下标作为第二关键字即可,容易发现这样做之后转化为了两两不同的情况.

Example2([SDOI2010]地精部落)

注意到第\(n\)个元素一定是山峰.所以我们考虑用第\(n\)个元素分割整个区间为两部分.

\(f_n\)\(n\)个元素且开头为山谷的答案.枚举第\(n\)个元素在位置\(k\)(\(k - 1\)是奇数),则\(f_k f_{ n - 1 - k } \binom{ n - 1 }{ k } \rightarrow f_n\).

Example3

给定数组\(a\),每次可以选择一个数删掉并把两边的数接起来,要求操作过程中不能出现相邻的数相同,求方案数.\(n \leq 500\).

考虑枚举最后选的点,那么这个点左右一定互不相干.我们假设\(f_{ l , r }\)为将\([ l , r ]\)删干净后再去删\(a_{ l - 1 } , a_{ r + 1 }\)的方案数,然后枚举\([ l , r ]\)中最后删哪个点即可做区间dp.

Example4([AGC039E] Pairing Points)

注意到这么一个事实:如果场上已经有了一个叉,那么接下来的边不能再穿过这个叉了.

首先需要破环为链,考虑从\(1\)号点这里断开,枚举\(1\)号点连接哪个点,然后就可以让\(( 2 , 2 n )\)这些点断开了.我们设计\(f_{ i , j , k }\)\([ i , j ] ( k )\)表示区间\([ i , j ]\)中的\(k\)向外连了一条边.答案是枚举\(1\)号点连了哪个点,也就是\(\sum_{ i = 3 }^{ 2 n - 1 } f_{ 2 , 2 n , i }\).

于是我们现在的问题在于如何求\(f_{ i , j , k }\).由于边要联通,所以与\(k\)相连的这条边必然被\([ i , j ]\)中的某两个点所连接的边穿过.我们考虑枚举最靠外的那条边,假设为\(x \leftrightarrow y\).这样整个区间被分为了两个部分:\([ i , k ] ( x ) , [ k , j ] ( y )\).但是问题并没有得到解决.因为\([ i , x ]\)\([ y , j ]\)之间的确不可能出现连边了,但\([ x , k ]\)\([ k , y ]\)之间仍然可能出现连边.但我们发现:在\([ i , k ]\)中一定存在一个分界线,使得分界线两侧是连到不同的两边的.

我们不妨再枚举一下这两个分界线,分别设为\(p , q\).现在整个区间被分为了三个部分:\([ i , p ] ( x ) , [ p , q ] ( k ) , [ q , j ] ( y )\),三个部分之间并没有连边,于是成功将区间拆分.

这个故事告诉我们:拆分区间的很重要的条件是:将一个区间拆分为若干相互无联系的区间,而我们的重点就是找到一种方式使得区间间相互无联系.

Example5([AGC035D] Add and Remove)

首先自然想到区间dp.但是难以处理的是如果一个区间\([ l , r ]\)中间删掉一个点\(p\)之后,\([ l , p - 1 ]\)\([ p + 1 , r ]\)会拼起来,仍然会相互影响.

换一种方式,我们找到\([ l + 1 , r - 1 ]\)中最后删除的点\(p\),这样区间\([ l , r ]\)的答案就是最终三个数的答案.这么枚举的好处是,我们发现删除\([ l + 1 , p - 1 ]\)的时候,对\(p\)产生的贡献和删除\([ p + 1 , r - 1 ]\)的时候对\(p\)的贡献是完全独立的,他俩可以分开.

再看每个位置的贡献,我们考虑计算出这个位置会对答案贡献多少倍,不妨假设\(a_l\)贡献了\(x\)倍,\(a_r\)贡献了\(y\)倍,那么由于\(a_p\)会两边都贡献到,所以\(a_p\)会对答案贡献\(x + y\)倍.

于是设计一个dp是:\(f_{ l , r , x , y }\)表示删除\([ l + 1 , r - 1 ]\)后,\(xa_l + ya_r\)最小是多少.自然有\(f_{ l , r , x , y } = \min \{ f_{ l , p , x , x + y } + f_{ p , r , x + y , y } + ( x + y ) a_p \}\).

至于复杂度,前两维肯定是\(n^2\)的空间复杂度,而后两维则意味着每次向下会由两个转移而来,最多转移\(n\)层,因此是\(2^n\)的空间,于是时间复杂度不会超过\(O ( n^3 2^n )\),其实经过一些奇怪计算应该是不会超过\(O ( 2^n )\)的.

Example6([CF607B]Zuma)

这个题的关键在于拆分区间,因此一定要判断哪个点是最后删除的.

我们不妨设\(f_{ l , r }\)表示删除\([ l , r ]\)区间的代价.接下来我们无非要枚举\(k\),使得\(k\)是最后删的.但发现这很难处理.

所以我们怎么办呢?我们考虑判断边界是如何删掉的.比如\(l\),它要么是自己被删,要么一定是找到一个和它一样的点,这两个点一起删.我们注意到如果\(a_l = a_k\),那么这等价于\(f_{ l + 1 , k - 1 } + [ l = k - 1 ] + f_{ k + 1 , r }\).因此可以做区间dp了.

Example7(LOJ 3215)

首先考虑一下\(m = 2^k - 1\)的情况,首先我们要判断有几个数最高位是\(1\),然后接下来判断第二位哪些数字是\(1\).

我们发现这类似一个拆分区间的过程,因为当我们决定了最高位之后,最高位是\(1\)的就一定大于最高位是\(0\)的了,这两个区间就没有影响了.因此可以设\(f_{ l , r , k }\)表示\([ l , r ]\)这个区间,前面已经有了\(k\)\(1\)的最大贡献.

那么对于\(m \ne 2^k - 1\)的情况我们怎么办呢?我们只需要类似数位dp那样在状态里加一个lim防止超过\(m\)就行了.

相互独立

Example1(2019zrtg十连测day1 origami)

看上去很不好做,先考虑宽为\(1\)怎么做.

这个时候放在最下面的显然是一段区间,不难发现有一个暴力做法是,我们枚举这段区间\([ l , r ]\),然后看\([ 1 , l - 1 ]\)\([ r + 1 , m ]\)能不能折进来.也就是判断以\(r\)\(r + 1\)为中心的回文串最大长度以及在这个范围内有没有已经折进来的区间.想到这一步,不难发现左右是独立的.

于是我们设\(f_i\)表示能不能折成以\([ 1 , i ]\)为最下层,\(g_i\)表示能不能折成\([ i , n ]\)为最下层,那\([ l , r ]\)能折出来当且仅当\(f_r = g_l = 1\),做个前缀和就可以知道有多少个区间能折出来.

通过上面的启示,我们不难发现横着折和竖着折也是相互独立的,于是分别算出答案后乘起来就好.

Example2(CF1616G Just Add an Edge)

我们来一点一点捋这个题:

首先,任意一条路径一定形如\(1 \rightarrow x \cup y \rightarrow n\),并且\(1 \rightarrow x\)\(y \rightarrow n\)不交,然后添加边\(x \rightarrow y\).

那么什么时候\(1 \rightarrow x\)\(y \rightarrow n\)没有交并且他们的并是\([ 1 , n ]\)呢?考虑将\(1 \rightarrow x\)这条路径上的点染色为\(0\),\(y \rightarrow n\)上的点染色为\(1\),由于边只有从前往后的,因此\([ 1 , y - 1 ]\)必然为\(0\),\([ x + 1 , n ]\)必然为\(1\).至于中间部分一定是一段一段地跳跃.

我们用dp做中间的跳跃过程,具体地,假设我们已经确定了\(y\),现在想要找到\(x\),我们现在假设染色的末尾是\(( i , i + 1 )\),也就是\(i\)染色和\(i + 1\)的染色不一样,然后不断向后接上就行.

那么怎么优化这个dp呢?我们找到任意一个\(p\),满足\(p \nrightarrow p + 1\),那么\(p\)\(p + 1\)永远不可能染同种颜色,我们直接以它为断点,自然发现\(p\)的左右两部分独立.

然后就是这题的细节部分,首先是计数的时候有可能算上了\(p \rightarrow p + 1\)这条边,要特判.另外的问题是会发现首尾的位置很特殊,这里的做法是建立\(0\)\(n + 1\)两个虚点,向所有点连边.

总之\(O ( nm )\)的dp是自然的,而且会发现这个是一个类似连续性的东西,因此想到了在中间找断点中间合并,进一步发现左右两部分无关.

费用提前/延后计算

有的时候,我们注意到一个费用是很难及时算到dp数组里的,但是这个费用可能可以早在之前题前算上或之后再补上.

Example1([22zr提高组十连测day3]多)

首先考虑已知一个序列,如何快速求它最后有几个位置不是\(0\).考虑从后往前枚举,每次判断当前数是否在以前已经枚举到过,如果枚举过就将其\(- 1\)并重复判断操作,直到为\(0\)或得到一个没有出现过的数.

考虑设计dp状态,判断一个位置是否能是\(0\)相当于判断后面的已知序列的\(mex\),这个要记入状态中,于是考虑设\(dp_{ i , j }\)表示当前到了第\(i\)个位置,后面的数的\(mex - 1\)\(j\)的方案数.

但是如果直接这么设会发现,当前\(i\)的加入有可能会改变\(mex\)的值,而这个改变是很难处理的,因为如果\(i\)位置选择了\(j + 1\)这个数字,那么\(mex\)要向上伸展到某一个值,而如果不选择\(j + 1\),也有可能选择一个更大的值后不断落到\(j + 1\),这意味着我们转移时需要枚举补上\(j + 1\)这个数字后的\(mex\)并用刷表法转移.

不妨设这个数字是\(k\).如果我们插入一个数字后直接更新当前的答案,可以发现这个\(k\)是没有办法处理的.所以考虑延后计算费用,即当我们插入的数字并没有引起\(mex\)的改变的时候,忽略此时带来的组合数贡献(因为这个数字可以任选,可以理解为将其暂时存下来后来需要它的时候再把它乘入答案);当我们引起改变的时候,我们从之前存下来的那些数字中取出一些补全\([ j + 2 , k ]\)这些数字.

另外,注意到计算组合数的时候每个数字有两个,没有办法判断当前还剩下哪些数字,不妨直接认为两个相等的数字本质不同,算完答案后再整体除以\(2^{ n }\).

Example(2022zrnoip十连测day9-消失(vanish))

\(O ( n^3 )\)的暴力是显然的:设\(f_{ i , j , k }\)表示目前考虑到第\(i\)个位置,前面还有\(j\)个A,已经选了\(k\)个B的方案数,对A也类似做一做,最后枚举中点合并即可.

问题在于如何优化到\(n^2\).

第一反应是删掉一维,但是这三维好像哪一位都不能删:第二维要累积答案,第三维要最后做合并.但是,注意到第二维和第三维可以合并!换句话说,我们做一个费用提前计算,每次加入A的时候,枚举它接下来要杀掉几个B,那我们接下来就额外多需要一些B.于是我们设\(f_{ i , j }\)表示目前考虑到\(i\),还需要\(j\)个B才能凑齐\(c_B\)个B的答案,就可以实现了.

咋说呢,大概是发现答案和后两维有关,而且注意到后两维之和是不大的,于是考虑把它俩合并起来做费用提前计算.

建立双射

Example1([SDOI2010]地精部落)

\(f_{ i , j }\)表示长度为\(i\),开头为山峰且高度为\(j\)的方案数;\(g_{ i , j }\)表示长度为\(i\),开头为山谷且高度为\(j\)的方案数.注意到这俩显然是一个双射,也就是\(f_{ i , j } = g_{ i , i - j + 1 }\).

首先我们可以插入一个数,假如插入的数是山峰,那原本的所有大于等于\(j\)的数都向上平移一格,于是自然有:\(f_{ i , j } = \sum_{ k = 1 }^{ j - 1 } g_{ i - 1 , k } = \sum_{ k = 1 }^{ j - 1 } f_{ i - 1 , i - k }\).

另外,这个式子可以稍微转化为:\(f_{ i , j } = f_{ i - 1 , i - j + 1 } + f_{ i , j - 1 } = g_{ i - 1 , j - 1 } + f_{ i , j - 1 }\).

上式可以这么理解:我们讨论一下\(j\)\(j - 1\)是否相邻,如果相邻必然是\(j\)是山峰,\(j - 1\)是山谷,不然则交换它俩后也仍然是合法的序列.

Example2(2019zrtg十连测day1 group)

首先注意到\(2 k \leq n \land nk \leq 10^5\),不难发现\(k \leq 500\).

冷静一下,发现如果我们把所有组长列出来按照经验排序,再把所有组员列出来按照经验排序,然后按照顺序匹对一定是最优的.

再冷静一下,类似卡特兰数,这等价于先把所有人按照经验从小到大排序,然后任意前缀选择的组长数量大于等于组员,枚举这个差量和前面选的组长的总量就可以做到\(O ( nk^2 )\).当然其实只要控制组长的数量大于等于组员的数量即可.

注意经验相同的话要让想当组长的到前面.

另外当时还推了个性质:都可以的人群中一定存在一个分界点\(w\),使得成为组长的经验\(\geq w\),成为组员的经验\(\leq w\),但是没用上这个性质.

Example3(AGC056B)

双序列计数,考虑把\(x\)双射到某个东西上.

考虑最后的图一定是个\(DAG\),但同层之间没有啥限制,我们不妨假设同层的最左侧是最大值,这样就完成了映射.

\(dp_{ l , r , mx }\)表示只考虑\([ l , r ]\)这一段的线段,然后最大值所在位置需要\(\geq mx\)的答案.转移的话枚举一手最大值扔哪,然后大概能做?

分维处理

简单来说就是如果问题有两维,我们找到简单的那一维处理.

Example1([CF1621G]Weighted Increasing Subsequences)

动态规划的优化

递进转移

瞎起的名,主要用于大量字符串算法.比如SA中的求height.

Example1

\(m\)种礼物,每种礼物有无数个(有有限个也能做),\(n\)个朋友,第\(i\)个朋友喜欢第\(j\)个礼物的概率是\(p_{ i , j }\),\(\forall i , \sum p_{ i , j } = 1\).

现在你可以选\(n\)件礼物.购买完成后你会按照朋友的编号逐个进行以下操作:如果自己手上的礼物有他喜欢的那一个,就将那个给他.求一种策略,最大化拿到喜爱的礼物的朋友个数的期望值.

\(n \leq 3000 , m \leq 300\).

首先一个显然的想法是:不同礼物对期望的贡献是独立的,也就是和的期望等于期望的和,我们只需要算出每个礼物的贡献即可.进一步地,我们需要求出\(g_{ i , j }\)表示第\(i\)种礼物一共选了\(j\)个,被拿走的期望个数.然后我们只需要对其做背包就可以了.

那么\(g\)怎么求呢?这个是简单的,我们设\(f_{ i , j }\)表示喜欢第\(i\)种礼物的人有\(j\)个的概率,不难发现\(g_{ i , j } = \sum_{ k = 0 }^n \min \{ j , k \} f_{ i , k }\).递推式就有\(g_{ i , j } = g_{ i , j - 1 } + \sum_{ k = j }^n f_{ i , k }\).\(f\)同样是做一个背包.

但是,这两个背包的复杂度都是\(O ( n^2 m )\)的.我们需要对它们进行优化.

先看最后求答案的背包:自然的想法是,不难发现\(g_{ i , j }\)满足四边形不等式,而其转移是经典的\(k\)点最短路,因此可以用决策单调性优化.

但实际上有点多此一举,事实上我们这么考虑:由于\(g_i\)是上凸函数,它的斜率逐渐减少,那么我们就必然是能选小的就选小的.我们可以设计一个贪心来解决这个问题:记录下来当前每种礼物选了几个,设为\(c_i\),每次选当前\(g_{ i , c_i + 1 } - g_{ i , c_i }\)最大的那个即可,这可以用堆实现.为啥这个是对的呢?因为\(c_i\)越大,能有的贡献就越小,不可能出现为了后面的贡献而让前面吃亏的情况,这就可以贪心了.于是第一个背包得到了解决.这里复杂度\(O ( n^2 \log n )\),不太确定有没有\(O ( n^2 )\)的做法.

但是第二个背包,也就是\(f\)怎么求呢?我们发现我们没有必要把\(g\)全都求出来,只需要求目前需要的一部分就可以了,由于\(\sum f = 1\),因此后缀和可以改为前缀和,考虑到每往后推一位是\(O ( n )\)的,但是只会往后推总共\(O ( n )\)位,因此这里复杂度\(O ( n^2 )\).

Example2

给一个字符串,求一个最大长度\(L \leq \frac{ n }{ 2 }\),使得前\(L\)个字符与后\(L\)个字符循环同构.

不难发现循环同构一定长这样:

\[ ABSBA \]

我们枚举\(A\)的长度,然后就只需要求\(B\),设\(f_{ i }\)表示字符串去掉开头和结尾的\(i\)个字符后的border,有\(f_{ i - 1 } \leq f_i + 1\).然后就做完了.

反向操作

其实本质上是因为,DAG把边反向后仍然是一个DAG,这意味着我们大部分dp都可以进行反向操作.

Example1(CF1810G)

其实这题有一个很自然的容斥做法,但我们先略过.

一般而言先考虑对于每个\(k\)暴力做.那怎么维护最大前缀和这个东西呢?如果我们从左往右扫,其实是很难维护的.因为我们无法接受加一维以维护它.更进一步为什么无法维护呢?因为你新加一个元素,它是不会影响前面的前缀和的,只会影响一个.这导致你的取\(\max\)操作很艰难.但如果!我把这个dp反过来,我设\(f_{ i , j }\)表示从后往前dp到\(i\),当前的最大前缀和是\(j\)的概率是多少,这个dp的转移极其简单:

\[ P \times f_{ i , j } \rightarrow f_{ i - 1 , \max \{ 0 , j + a_{ i - 1 } \} } \]

最后在\(f_{ 1 , j }\)处乘上\(h_j\).

但是这样是\(O ( n^3 )\)的,怎么办呢?

考虑把这个dp反过来!我们设\(g_{ i , j }\)表示如果初始只有\(f_{ i , j } = 1\),dp到最后的答案是多少.于是只需要:

$$ \[\begin{aligned} P \times g_{ i - 1 , \max \{ 0 , j + a_{ i - 1 } \} } & \rightarrow g_{ i , j } \\ \end{aligned}\]

$$

我认真考虑过这个\(P\)应该乘在哪边.实际上确实应该在左边.原因比较简单,因为答案是一串乘法,你不能把这些\(P\)变成除法.但还有一个问题是,为什么反向的时候没有把这些反向呢?

原因是这类型dp比较特殊,我们要算的其实是一个类似DAG路径上的信息,因此边权无需改变.

矩阵加速

Example1(luoguP4007小Y和恐怖的奴隶主)

首先考虑直接将随从的状态压起来,拿组合数分析一下会发现状态数大概小于等于\(200\).也就是说转移矩阵大概是\(200 \times 200\)的,设状态数为\(S\).

继续考虑,如果直接做的话复杂度是\(O ( TS^3 \log n )\),过不了.

我们考虑将一个\(n\)\(w\)进制下分解,然后预处理每一位所对应的矩阵,这样复杂度来到了\(O ( wS^3 \log_w n + TS^2 \log_w n )\),平衡一下复杂度即可,大概取\(w = 4\)会比较优秀.

Example2([NOI Online#3提高组]魔法值)

重新定义矩阵乘法:用\(\oplus\)替换原本的\(+\),然后用邻接矩阵作为转移矩阵.

直接做仍然过不了,不过可以用和上面那个题一样的方法来优化复杂度.

Example3([CF 1474F])

首先需要注意到,LIS的起点和终点一定在这条线的拐角处,也就是山谷和山峰处.

LIS的长度是好求的.问题在于计数上.

首先枚举一下LIS的起点和终点,但是接下来似乎怎么dp都需要和值域有关.而且如果从起点走到终点,判断中间具体的方案数,这个东西似乎也不能快速处理,一条线上的似乎也很难捆绑更新.

我们冷静一下,令\(f_i = \sum_{ j , a_j = a_i - 1 } f_j\),这个东西一条直线上的位置不能捆绑更新的原因在于,随着我们从左往右走,是需要不断更新后面的\(\sum\)的值的,这一点很难处理.每次移动需要加入一条横线上的点对应的\(f\).

再冷静一下,既然从左到右扫不行,我们能不能考虑从下往上扫呢?考虑设\(f_{ i , j }\)表示所有\(a_x = i\)\(x\)中第\(j\)小的\(x\)的答案,我们仍然可以从下往上扫.

但是,这么扫的复杂度仍然和值域有关.这怎么办呢?这个加入可规律多了,注意到在经过一个山峰或山谷之前,我们需要处理的点的数量和相对顺序都是恒定的,而它们的转移也之和上一次转移(上一条横线)有关,于是可以直接拿矩阵加速这个过程.

Example4([CF 1152F2])

注意到\(m\)\(k\)很小,这一定是突破口.

又注意到如果\(a_{ i + 1 } > a_i\),那么限制很强,反之很弱.而且又要求没有相同的数字.考虑从小到大加入数字,这样每加入一个数字\(x + 1\),我们考虑它只能插入\([ x + 1 - m , x ]\)后面,我们直接用一个二进制数\(S\)表示\([ x + 1 - m , x ]\)中的数字是否存在,然后就可以在转移上直接调用\(popcount ( S )\).设\(dp_{ i , j , S }\)表示目前考虑完了数字\(i\),插入了\(j\)个数字,存在情况是\(S\).直接对它做矩阵加速就可以做到\(O ( ( 2^m k )^3 \log n )\).

Example5([NOI2020] 美食家)

\(dp_{ i , j }\)表示第\(i\)天走到城市\(j\)的最大收益,一眼矩阵加速.

但是有两个问题需要解决:

第一个问题是,怎么处理美食节.这个没什么,在两个美食节之间做矩阵加速,在美食节节点上特殊处理一下就行.不过这样复杂度要乘上\(k\).我们可以一开始就预处理出转移矩阵的二的幂次,然后这里就可以加快速度.

第二个问题是,怎么处理边权.一个自然的想法是拆边,但边很多,拆不过来.怎么办呢?我们可以拆点.将一个点拆成若干个点连起来,对于一条边就找到对应的点连过去就行.

分步合并

大概是有的时候如果询问比较多,我们可能需要处理前缀/后缀数组然后拼起来答案.

这个时候我们会发现,如果要拼起来答案就要枚举一个区间,但是实际上可以一步一步来.

Example([2022qbxt国庆Day6]permutation)

首先遇到排列先扔平面直角坐标系上.

考虑合法序列一定长什么样,如果我们把这个序列的若干个下降子段拿一个矩阵括起来,那这些矩阵显然横纵坐标都不能相交.

我们设\(f_{ l , r }\)表示\(a_l\)\(a_r\)必选的前提下,\([ l , r ]\)这个区间的下降子序列个数.

然后,我们考虑枚举删掉点,对着剩下来的序列做dp.

考虑设\(dp_{ i , j }\)表示前\(i\)个点,最大值为\(j\)的方案数,不难发现最后一个矩阵的最小值一定是\(a_{ i }\).然后\(dp_{ a , b } = \sum_{ i < a , j < b } dp_{ i , j } f_{ i + 1 , a }\).

这个转移是\(n^4\)的,但是这显然是一个前缀和的形式,于是做一下二维前缀和就可以做到\(n^2\),这样我们就得到了一个复杂度\(O ( n^3 )\)的东西.

继续考虑,由于是多个点,我们考虑维护前缀后缀然后在这个点拼起来.注意到,如果我们想求这个点不选的方案数,那还需要枚举它左右两边选的点,很麻烦,所以我们求一下这个点必选的方案数.这样我们每次需要枚举这个点\(i\),它所在矩阵的最左边的点\(k\),最右边的点\(k\),然后此时的答案为\(pre [ j - 1 ] [ a [ k ] - 1 ] \times nxt [ k + 1 ] [ a [ j ] + 1 ] \times f [ j ] [ i ] \times f [ i ] [ k ]\).

冷静一下,这样一步枚举了两边的分界点,所以可能不是很优秀,我们一步一步来.

\(g_{ i , j }\)为接下来我们要选\([ i , j ]\),\(i\)是矩阵左端点,\(j\)任意且这两个点必在矩阵中,左右两边的方案数.初始条件\(g_{ i , j } = pre [ i - 1 ] [ a [ j ] - 1 ] \times nxt [ j + 1 ] [ a [ i ] + 1 ]\).

然后我们不断转移右端点,将右端点往里缩,这一步可以使用树状数组优化,最后更新答案即可.

很厉害.

合并更新

Example(2022zrtg十连测day7 Zero)

\(k = \max \{ i , j \}\),首先可以求出\(x , y , z\)分别表示:

  1. \(x\):只包含第一行的格子的以\(k\)为右端点的和为\(0\)的最小矩形的左端点\(- 1\).

  2. \(y\):只包含第二行的格子的以\(k\)为右端点的和为\(0\)的最小矩形的左端点\(- 1\).

  3. \(z\):同时包含两行的格子的以\(k\)为右端点的和为\(0\)的最小矩形的左端点\(- 1\).

那么自然有转移:

\[ \begin{gathered} f ( i , k ) \leftarrow \max \{ f ( i , k - 1 ) , f ( i , y ) + 1 \} \\ f ( k , j ) \leftarrow \max \{ f ( k - 1 , j ) , f ( x , j ) + 1 \} \\ f ( k , k ) \leftarrow \max \{ f ( k , k - 1 ) , f ( k - 1 , k ) , f ( z , z ) + 1 \} \end{gathered} \]

转移正确的原因是两维转移顺序无所谓,所以可以乱转移.

冷静一下这个过程,我们先只考虑第一个转移:注意到\(f ( i , k )\)关于\(i\)不降,于是显然当\(f ( i , y ) \ne f ( i , k - 1 )\)的时候才会由\(f ( i , y ) + 1\)转移过来.我们不妨设\(p_i\)表示最小的位置满足\(f ( i , p_i ) = f ( i , k - 1 )\),那转移也就是\(f ( i , k ) \leftarrow f ( i , k - 1 ) + [ p_i \leq y ]\).并且每进行一次转移,都会满足\(p_i \leq y\)\(p_i\)设为\(k\).

也就是说我们需要维护:我们令一个点为它对应的\(i\)在当前\(k\)\(f\)值,将这个点放到\(p_i\)位置上.然后我们每次找到\(y\)并把所有在\(y\)位置前的点都合并到\(k\)这个点上,并打一个加法\(tag\),这显然可以并查集启发式合并.

把前两个转移这么一起做,然后用二分可以得到两个转移分别的\(p_k\).

最后还需要处理一下\(f_{ k , k }\),暴力转移即可.

有一个问题是为啥能想到按照\(\max \{ i , j \}\)为顺序进行转移,这里是由于转移顺序无区别,我们需要规定一个顺序进行转移,于是考虑到找到较长的那一部分进行转移.

交换状态和值

通常是dp值较小而状态较大的情况,而且二者间通常需要满足单调性.

Example1(CF1620F)

首先讨论一下最大值最小值之类的不难发现:这题是二分图的充要条件是\(\nexists 1 \leq i < j < k \leq n\),\(a_i > a_j > a_k\).

然后相当于是整个序列可以拆分成两个上升子序列,一个想法是\(dp_{ i , j }\)表示现在做到\(i\),另一个上升子序列的终点是\(j\),是否合法.然后继续做.但这样复杂度挂掉了.

咋优化咧?注意到dp状态很大而值很小,且显然在\(i\)一定的情况下,\(j\)的值越小越容易满足.所以设\(dp_i\)表示一个上升子序列的终点是\(i\),另一个上升子序列的终点最小是多少,这样就可以做了.

Example2(AGC033D)

首先自然的设计是\(dp_{ l , r , u , d }\),然后优化一下就是\(O ( n^4 )\).然后咋做?

注意到答案不超过\(\log\)级别,所以设\(dp_{ l , r , u , c }\)表示答案为\(c\)的时候,最大的\(d\)是多少.然后就\(O ( n^3 \log n )\).

Example3

给定一个序列,两个人博弈.Alice每次可以使序列最左边的数\(a_i\)减去\([ 1 , a_i ]\)中的一个数字,减成\(0\)就删掉.Bob可以对最右边的数做类似的操作,不能操作者输.问结果.\(( n \leq 2000 )\)

先考虑一个\(O ( n^2 a^2 )\)的dp,比较显然,因为一个人取数显然要么取\(1\)要么全取,又发现不可能两个人一起取一堆(先取的那个人取完就赢了),于是设\(dp_{ l , r , x , y }\)表示目前Alice在取第\(l\)堆,Bob在取第\(r\)堆,第\(l\)堆为\(x\),第\(r\)堆为\(y\)的情况下谁赢.直接转移.

诶,好像优化不动了,无论咋做都要知道当前这堆数字是啥啊,那就一定要把\(a\)存状态里诶.

能不能再更新一下策略,注意到最后Alice如果要全选的话,剩下的是\(1\)还是更大的数好像无所谓.那:如果\(a_1 = x\)的时候,Alice能赢,那\(a_1 = x + 1\)的时候Alice一定能赢.也就是这个东西满足单调性.又冷静一下,如果两个人不断一直持续选\(1\),那最后一定会选到一个人清空堆为止.而且清空堆的那个一定输了.因为如果清空了还赢了,那他一开始就直接清空了.不可能一开始选着选着一个人还没清空堆另一个人就跑了.这个性质启示我们或许后两维可以删掉一维,因为大部分情况下那一维都应该等于\(a_l\)\(a_r\).

然后咧?另一维怎么去掉呢?

等一下,我们开一个四维的dp存\(0 / 1\)是不是太奢侈了?

所以我们把一个状态改为dp的值,设\(dp_{ l , r }\)表示当前Alice在\(l\),Bob在\(r\),Bob还没动\(a_r\)的前提下,\(a_l\)至少要是多少Alice才能赢,Bob做一个类似的dp.最后只需要比较\(dp_{ 1 , 1 }\)\(a_1\)的大小就行.

问题来了,这玩意咋转移啊?

首先,如果当前Alice开始选\(l\),Bob开始选\(r\),那Alice的获胜条件显然是\(dp_{ l , r } \leq a_r\)

如果可以全选(也就是Alice开始选\(l + 1\),Bob开始选\(r\)的时候Alice能赢),就直接让\(dp_{ l , r } = 1\).不然,由于清空堆的人要输,所以Alice为了不输,必须要让\(dp_{ l , r - 1 }\)也满足条件,一个自然的想法是\(dp_{ l , r - 1 } + a_r + 1\),但是这个值好像没有必要:因为Bob并不是只有会不断清空\(a_r\)的,如果目前的\([ l + 1 , r ]\)这个状态,Bob的值已经赢不了了,那我Alice就可以直接把左边清空.所以一旦Bob走到了不能稳赢\([ l + 1 , r ]\)的值,Bob就必须全清空,所以如果我们设\(g_{ l , r }\)是Bob的\(dp\)数组,那其实这里应该是\(a_r + 1 + dp_{ l , r - 1 } - g_{ l + 1 , r }\),因为Bob的策略一定是一步一步走到\(g_{ l + 1 , r }\)后清空,这个情况我们已经杀了他了.

Example4(uoj708)

自然的想法是\(dp_{ i , j }\)表示\(i\)子树内划分成\(j\)个连通块是否合法,然后我们发现如果\(j\)满足条件,那么\(j + 2\)一定满足条件(判掉一些边界情况).

斜率优化

一般的斜率优化就略了.

值得一提的是,斜率优化还有一种理解方式是:将前面的点当作直线,后面的当作一条平行于\(y\)轴的直线进行查询.

Example1(Codechef TSUM2)

点分治+斜率优化,注意需要使用第二种理解方式的斜率优化.

不过第一种应该也可以用.

WQS二分

能用WQS二分解决的问题通常形如:需要在\(n\)个物品中选择恰好\(m\)个,使得最后答案最大.并且如果令\(f_i\)表示选了\(i\)个的最大答案,\(f_i\)必须是凸函数且是单调不降的.

遇到这种问题,我们通常二分一个数\(C\),每选择一个物品就减去\(C\)的答案.不难发现这样我们一定能逼近\(f_m\).

四边形不等式

对于定义在\(\mathbb{ Z }\)上的二元函数\(w\),若对定义域上任意\(a , b , c , d ( a \leq b \leq c \leq d )\)都有\(w ( a , c ) + w ( b , d ) \leq w ( a , d ) + w ( b , c )\),也就是交叉小于包含,则称函数\(w\)满足四边形不等式.如果等式成立,那么我们称其满足四边形恒等式.

不难发现这意味着:\(w\)所形成的矩阵中的任意一个子矩阵的差分(左上角+右下角-左下角-右上角)都小于等于\(0\).

如果它还满足\(\forall 1 \leq l ' \leq l \leq r \leq r ' \leq n , w ( l , r ) \leq w ( l ' , r ' )\),我们称其满足区间包含单调性.

需要声明的一点是:四边形不等式只能处理\(\min\)型dp的问题,对于\(\max\)型dp需要取相反数改成\(\min\).

判定/性质定理

定理1

若二元函数\(w ( x , y )\)满足\(w ( a , b ) + w ( a + 1 , b + 1 ) \leq w ( a , b + 1 ) + w ( a + 1 , b )\).其中\(a < a + 1 \leq b < b + 1\),则\(w\)满足四边形不等式.

证明:

对于\(a + 1 < c\)

$$ \[\begin{aligned} w ( a , c ) + w ( a + 1 , c + 1 ) & \leq w ( a , c + 1 ) + w ( a + 1 , c ) \\ w ( a + 1 , c + 1 ) & \leq w ( a , c + 1 ) + w ( a + 1 , c ) - w ( a , c ) \\ \end{aligned}\]

$$

同时有:

$$ \[\begin{aligned} w ( a + 1 , c ) + w ( a + 2 , c + 1 ) & \leq w ( a + 1 , c + 1 ) + w ( a + 2 , c ) \\ w ( a + 1 , c ) + w ( a + 2 , c + 1 ) - w ( a + 2 , c ) & \leq w ( a + 1 , c + 1 ) \\ \end{aligned}\]

$$

联立得到:

\[ \begin{aligned} w ( a + 1 , c ) + w ( a + 2 , c + 1 ) - w ( a + 2 , c ) & \leq w ( a , c + 1 ) + w ( a + 1 , c ) - w ( a , c ) \\ w ( a + 2 , c + 1 ) + w ( a , c ) & \leq w ( a + 1 , c ) + w ( a + 2 , c + 1 ) \end{aligned} \]

同理可推至四边形不等式定义式.

事实上,这意味着一个\(2 \times 2\)的子矩阵的差分满足条件,那么自然满足四边形不等式,无需推导.

定理2

\(w_1 ( l , r ) , w_2 ( l , r )\)满足四边形不等式(或区间包含单调性),则\(\forall c_1 , c_2 \geq 0\),\(( c_1 w_1 + c_2 w_2 )\)满足四边形不等式(或区间包含单调性).

证明显然.

定理3

\(\exists f ( x ) , g ( x )\)使得\(w ( l , r ) = f ( r ) - g ( l )\),则\(w\)满足四边形恒等式.当\(f , g\)单调递增时,\(w\)还满足区间包含单调性.

证明显然.

定理4

\(h\)是一个单调递增的下凸函数(一阶导数单调递增),若\(w ( l , r )\)满足四边形不等式和区间包含单调性,则复合函数\(h ( w ( l , r ) )\)也满足四边形不等式和区间包含单调性.

\(l_1 \leq l_2 \leq r_1 \leq r_2\),由于\(w\)满足四边形不等式,于是有:

\[ \begin{aligned} w ( l_1 , r_1 ) + w ( l_2 , r_2 ) & \leq w ( l_1 , r_2 ) + w ( l_2 , r_1 ) \\ 0 & \leq w ( l_1 , r_1 ) - w ( l_2 , r_1 ) \leq w ( l_1 , r_2 ) - w ( l_2 , r_2 ) \end{aligned} \]

\(t = w ( l_1 , r_2 ) - w ( l_2 , r_2 )\),我们有:

\[ \begin{aligned} w ( l_1 , r_1 ) & \leq w ( l_2 , r_1 ) + t \\ w ( l_1 , r_2 ) & = w ( l_2 , r_2 ) + t \\ h ( w ( l_1 , r_1 ) ) - h ( w ( l_2 , r_1 ) ) & \leq h ( w ( l_2 , r_1 ) + t ) - h ( w ( l_2 , r_1 ) ) \\ h ( w ( l_1 , r_2 ) ) - h ( w ( l_2 , r_2 ) ) & = h ( w ( l_2 , r_2 ) + t ) - h ( w ( l_2 , r_2 ) ) \end{aligned} \]

不妨令\(\Delta h ( x ) = h ( x + t ) - h ( x )\),由于\(h\)是下凸函数,所以\(\Delta h\)函数单调递增.

那么也就有:

\[ \begin{aligned} h ( w ( l_1 , r_1 ) ) - h ( w ( l_2 , r_1 ) ) & \leq \Delta h ( w ( l_2 , r_1 ) ) \\ h ( w ( l_1 , r_2 ) ) - h ( w ( l_2 , r_2 ) ) & = \Delta h ( w ( l_2 , r_2 ) ) \end{aligned} \]

由于\(w ( l_2 , r_1 ) \leq w ( l_2 , r_2 )\),所以\(\Delta h ( w ( l_2 , r_1 ) ) \leq \Delta h ( w ( l_2 , r_2 ) )\)于是:

\[ \begin{aligned} h ( w ( l_1 , r_1 ) ) - h ( w ( l_2 , r_1 ) ) & \leq h ( w ( l_1 , r_2 ) ) - h ( w ( l_2 , r_2 ) ) \\ h ( w ( l_1 , r_1 ) ) + h ( w ( l_2 , r_2 ) ) & \leq h ( w ( l_1 , r_2 ) ) + h ( w ( l_2 , r_1 ) ) \end{aligned} \]

证毕.

定理5

\(h\)是一个下凸函数(一阶导数单调递增),若\(w ( l , r )\)满足四边形恒等式和区间包含单调性,则复合函数\(h ( w ( l , r ) )\)也满足四边形不等式.

证明类似定理4,因为满足四边形恒等式所以不必用到\(h\)单调递增的性质.

决策单调性

对于形如\(f_i = \min_{ 1 \leq j < i } \{ f_j + w ( j , i ) \}\)的状态转移方程,记\(p_i\)\(f_i\)的最优决策.若\(p\)\([ 1 , n ]\)上单调不降,则称\(f\)具有决策单调性.

值得一提的是,我们也可以把题目中的\(\min\)改为\(\max\),并且把\(+ w\)改为\(- w\),那么下面的结论同样成立.

最短路型dp

定理:对于形如\(f_i = \min_{ 1 \leq j < i }{ f_j + w ( j , i ) }\)的状态转移方程,若\(w\)满足四边形不等式,则\(f\)有决策单调性.

证明:

\(\forall i \in [ 1 , n ] , \forall j \in [ 0 , p_i - 1 ]\),根据\(p\)的定义,有:

$$ \[\begin{aligned} f_{ p_i } + w ( p_i , i ) & \leq f_j + w ( j , i ) \\ f_{ p_i } - f_j & \leq w ( j , i ) - w ( p_i , i ) \\ \end{aligned}\]

$$

而对于\(k \in [ i + 1 , n ]\),根据\(w\)的四边形不等式,有:

$$ \[\begin{aligned} w ( j , i ) + w ( p_i , k ) & \leq w ( j , k ) + w ( p_i , i ) \\ w ( j , i ) - w ( p_i , i ) & \leq w ( j , k ) - w ( p_i , k ) \\ \end{aligned}\]

$$

联立得到:

$$ \[\begin{aligned} f_{ p_i } - f_j & \leq w ( j , k ) - w ( p_i , k ) \\ f_{ p_i } + w ( p_i , k ) & \leq w ( j , k ) + f_j \\ \end{aligned}\]

$$

即:\(j\)\(k\)的更新一定不如\(p_i\)\(k\)的更新更优,因此\(p_k \in [ p_i , n ]\),因此\(f\)有决策单调性.

Example1(LOJ6039[雅礼集训2017Day5]珠宝)

首先发现代价很小但是物品很多,于是想到按照代价分类.然后同种代价要选肯定由价值从小往大选,这一段可以前缀和做.

于是我们设\(f_i\)表示价值为\(i\)的答案,自然有:\(f_i = \max \{ f_{ i - kc } + sum_{ c , k } \}\).

如果我们把\(c\)相同的分层,那这显然是一个最短路型dp,其中\(w ( i , j ) = sum_{ c , \frac{ i - j }{ c } }\).

显然这个转移只会让\(\mod c\)相同的相互转移,于是后面的\(w ( i , j )\)可以理解为一段数字的和,自然满足四边形不等式(\(\max\)也满足,因为交叉等于包含).

k点最短路型dp

对于形如\(f_{ x , j } = \min_{ i = 1 }^{ x - 1 } \{ f_{ i , j - 1 } + w_{ i , x } \}\)的状态转移方程,若\(w\)满足四边形不等式,则\(f\)有决策单调性.证明同上.

值得一提的是,如果形如\(f_x = \min_{ i = 1 }^{ x - 1 }{ w_{ i , x } }\),我们也可以看作\(k\)点最短路型的\(k = 1\)的特例.

Example1 基站选址

\(f ( i , j )\)为在第\(j\)个位置建造第\(i\)个基站的代价最小值,那么我们有转移:

\[ f ( i , j ) = \min_{ 1 \leq k < j } \{ f ( i - 1 , k ) + \sum_{ l = k + 1 }^{ j - 1 } w_l [ d_l - s_l > d_k ] [ d_l + s_l < d_j ] + c_j \} \]

考虑后面的式子,不难发现满足四边形不等式(可能出现包含的时候中间部分贡献一次答案,交叉的时候中间部分不贡献答案的情况),于是可以使用四边形不等式优化.

考虑使用二分维护决策单调性,那么后面的是一个经典的二维数点.但由于维护决策单调性时\(d_k\)单调递增,更新答案时\(d_j\)单调递增,于是可以直接使用线段树维护,复杂度\(O ( nk \log n )\).当然也可以直接用一个主席树维护.

也可以考虑分治维护,更加好写,复杂度\(O ( nk \log^2 n )\).

另外,我们可以再使用WQS二分处理第一维,复杂度\(O ( n \log k \log n )\).

Example2(CF gym 102984F)

自然的设计是\(f_{ i , j , k }\)表示前\(i\)个,已经打了\(j\)个,末尾有连续\(k\)个的最大价值.但是这个状态都已经超了.

我们可以用一下经典套路,把它转化为\(f_{ i , j }\)表示前\(i\)个,目前打了\(j\)个且第\(i\)个没打中,然后每次枚举一个打中了的区间,这样看上去就有了优化的可能性.而如果我们把它改成\(f_{ i , j }\)表示前\(i\)个,目前有\(j\)个没打中而且第\(i\)个没打中,这就是经典的k点最短路dp.

接下来我们尝试证明决策单调性:\(dp_{ i , j } = \max \{ dp_{ k , j - 1 } + \sum_{ l = k + 1 }^{ i - 1 } C_{ l - k } A_l + P \}\).

\(w ( l , r ) = \sum_{ k = l + 1 }^{ r - 1 } C_{ k - l } A_k + P\),接下来我们证明:\(w ( l + 1 , r ) + w ( l , r - 1 ) \geq w ( l , r ) + w ( l + 1 , r - 1 )\)即可.讨论一下每个\(A\)面前的系数就能发现这是成立的.

区间型dp

引理:在状态转移方程\(f_{ i , j } = \min_{ i \leq k < j } \{ f_{ i , k } + f_{ k + 1 , j } + w ( i , j ) \}\)中(通常\(f_{ i , i } = w ( i , i ) = 0 , f_{ i , i + 1 } = w_{ i , i + 1 }\)),如果\(w\)满足四边形不等式和区间包含单调性,那么\(f\)也满足四边形不等式.

证明:

只需证明\(f_{ i , j } + f_{ i + 1 , j + 1 } \leq f_{ i , j + 1 } + f_{ i + 1 , j }\)即可,考虑\(j - i = 1\)的时候,显然成立.

使用数学归纳,假设当\(b - a < k\)时,\(f\)满足四边形不等式,考虑\(j - i = k\)的情况:

\(f_{ i , j + 1 }\)的最优决策为\(x\),\(f_{ i + 1 , j }\)的最优决策为\(y\),则有:

$$ \[\begin{aligned} f_{ i , j + 1 } + f_{ i + 1 , j } & = f_{ i , x } + f_{ x + 1 , j + 1 } + w ( i , j + 1 ) + f_{ i + 1 , y } + f_{ y + 1 , j } + w ( i + 1 , j ) \\ \end{aligned}\]

$$

对于\(f_{ i , j }\)\(f_{ i + 1 , j + 1 }\)来说,\(x\)\(y\)不一定最优,所以有:

$$ \[\begin{aligned} f_{ i , j } + f_{ i + 1 , j + 1 } & \leq f_{ i , x } + f_{ x + 1 , j } + w ( i , j ) + f_{ i + 1 , y } + f_{ y + 1 , j + 1 } + w ( i + 1 , j + 1 ) \\ \end{aligned}\]

$$

\(w\)和归纳假设都可以比较两个式子右边的大小,最终得到:

$$ \[\begin{aligned} f_{ i , j } + f_{ i + 1 , j + 1 } & \leq f_{ i , j + 1 } + f_{ i + 1 , j } \\ \end{aligned}\]

$$

定理

\(p_{ i , j }\)\(f_{ i , j }\)的最优决策,若\(f\)满足四边形不等式,那么对于\(\forall i < j , 有 p_{ i , j - 1 } \leq p_{ i , j } \leq p_{ i + 1 , j } \\\).

证明:

\(p = p_{ i , j }\),\(\forall k , i < k \leq p\),因为\(f\)满足四边形不等式,所以有:

\[ \begin{aligned} f_{ i , k } + f_{ i + 1 , p } & \leq f_{ i , p } + f_{ i + 1 , k } \\ f_{ i + 1 , p } - f_{ i + 1 , j } & \leq f_{ i , p } - f_{ i , k } \end{aligned} \]

根据\(p\)定义,有:

\[ \begin{aligned} f_{ i , p } + f_{ p + 1 , j } & \leq f_{ i , k } + f_{ k + 1 , j } \\ f_{ i , p } - f_{ i , k } & \leq f_{ k + 1 , j } - f_{ p + 1 , j } \end{aligned} \]

由上两式移项联立,得到:

$$ \[\begin{aligned} f_{ i + 1 , p } - f_{ i + 1 , k } & \leq f_{ k + 1 , j } - f_{ p + 1 , j } \\ f_{ i + 1 , p } + f_{ p + 1 , j } & \leq f_{ i + 1 , k } + f_{ k + 1 , j } \\ f_{ i + 1 , p } + f_{ p + 1 , j } + w_{ i + 1 , j } & \leq f_{ i + 1 , k } + f_{ k + 1 , j } + w_{ i + 1 , j } \\ \end{aligned}\]

$$

因此对于\(f_{ i + 1 , j }\),\(p\)比任意的\(k < p\)更优,因此\(p_{ i + 1 , j } \geq p_{ i , j }\),另一方向同理.

四边形不等式判断凸性

判断一个函数的凸性只需判断\(f ( k ) + f ( k + 2 ) \geq 2 f ( k + 1 )\),而这只需证明\(k\)的时候的答案和\(k + 2\)时的答案可以调整出两个\(k + 1\)的答案(不一定是最小答案)并且这两个\(k + 1\)的答案的和小于等于\(k\)时和\(k + 2\)时的答案之和即可.

Example1(CF1661F)

首先考虑四个点\(( a , b , c , d )\),注意到其一定满足四边形不等式,也就是\(w_{ ac } + w_{ bd } \geq w_{ ad } + w_{ bc }\).

我们现在想证明,设\(f_k\)为新增\(k\)个传送机后的减少的答案,我们考虑证明\(f_k + f_{ k + 2 } \geq 2 f_{ k + 1 }\).

我们画出\(f_k\)时选的点和\(f_{ k + 2 }\)时选的点,注意到我们可以用这两次调整出两个\(k + 1\)的答案,并且这两个答案的和小于等于\(f_k + f_{ k + 2 }\),于是证明了最小的\(f_{ k + 1 }\)是更小的.

于是我们可以使用二分,每次二分一个最小增加量\(w\),然后对于每一段二分出在这一段中再增加一个传送机的增加量小于等于\(w\)的最大的传送机数量,然后就可以做了.

常用激活函数

Sigmoid函数

\(f ( x ) = \frac{ 1 }{ 1 + e^{ - x } } : ( - \infty , + \infty ) \to ( 0 , 1 )\).

\(f ' ( x ) = f ( x ) ( 1 - f ( x ) )\).

tanh函数

\(f ( x ) = \frac{ e^x - e^{ - x } }{ e^x + e^{ - x } } : ( - \infty , + \infty ) \to ( - 1 , 1 )\).

\(f ' ( x ) = 1 - f^2 ( x )\).

ReLU函数

\(f ( x ) = \max ( 0 , x ) : ( - \infty , + \infty ) \to ( 0 , + \infty )\).

Leaky ReLU函数

\(f ( x ) = \max ( \alpha x , x ) , 0 < \alpha < 1 : ( - \infty , + \infty ) \to ( - \infty , + \infty )\).

Softmax函数

\(f ( x_i ) = \frac{ e^{ x_i } }{ \sum_j e^{ x_j } }\).

损失函数

Least Square

\(\arg \min \sum_{ i = 1 }^n ( f ( x_i ) - y_i )^2 = \arg \min ( A \beta - Y \mid A \beta - Y )\).用最小二乘法取\(\hat \beta = ( A^T A )^{ - 1 } A^T Y\).

Cross Entropy

用错误的分布\(q\)来表示真实分布\(p\)的样本,则平均编码长度应该是:

\[ H ( p , q ) = \sum_i p ( i ) \log ( \frac{ 1 }{ q ( i ) } ) = - \sum_i p ( i ) \log{ q ( i ) } \]

此为交叉熵.

特别地,当最终样本只有两个的时候,例如Logistical Regression问题,可以写成:

\[ \begin{aligned} H & = - ( y \log a + ( 1 - y ) \log ( 1 - a ) ) \\ \frac{ \partial H }{ \partial a } & = - ( \frac{ y }{ a } - \frac{ 1 - y }{ 1 - a } ) \end{aligned} \]

那如果有多个呢?考虑直接对归一化条件作偏导,先有:

\[ \begin{aligned} H ( p , q ) & = - \sum_i p_i ( \log{ q_i } - \log ( \sum_j q_j ) ) \\ \frac{ \partial H ( p , q ) }{ \partial q_k } & = - \frac{ p_k }{ q_k } + \frac{ \sum p_k }{ \sum_j q_j } \\ & = - \frac{ p_k }{ q_k } + 1 \end{aligned} \]

再乘以softmax那里的\(q_k\),得到\(- p_k + q_k = - y_k + f ( x_k )\).

神经网络实现

通过若干隐藏层,假设最后的输出层为第\(L\)层,则:

  1. 对于第\(l\)层,取\(\vec{ z }_l = ( W_l )^t \vec{ a }_{ l - 1 } + \vec{ b }_l\).这里对\(W_l\)作转置的目的是写代码的时候需要用行向量.

  2. 对于第\(l\)层,取\(\vec{ a }_l = f ( \vec{ z }_l )\),这里意味着将每一个分量对\(f\)操作.

  3. 对于最终答案,取误差\(\mathcal{ L } = \frac{ 1 }{ m } ( \vec{ y } - \vec{ a }_L \mid \vec{ y } - \vec{ a }_L )\).

梯度下降法

换言之就是让\(w : = w - \alpha \frac{ \partial \mathcal{ L } }{ \partial w }\),其中\(\alpha\)是一个选定的小常数,也可以采用类似模拟退火的方式动态决定.事实上可以把各个位置分开,写作\(w_j : = w_j - \alpha \frac{ \partial \mathcal{ L } }{ \partial w_j }\).

另外,虽然是这么写,应当见到去掉下标\(k\)的记号仍然合理,无非是逐分量做此操作,因此下面如无特殊说明,运算均采用逐分量运算.例如可以定义\(\vec{ a } \circ \vec{ b }\)为两个向量逐分量相乘后得到的新向量,为表区分用\(\times\)表示正常的矩阵乘法.甚至采取\(( \vec{ a } - \vec{ y } )^2\)表示其自点积.坦白而言,笔者对此符号相当无奈,可也想不出什么更好的写法了.但总之这种写法总是强于部分参考资料上所将下标放上面的写作\(a^L\)的做法.笔者所能维持的精神数院人的唯一做法也只能是在下面加上向量符号,藉此泄愤.

顺便一提,应当见到\(\times\)\(\circ\)这两种运算比较随意,用线性映射来理解,你这个\(W \times\)任意作用在一个向量上就行.

误差反向传播

既然要用梯度下降法,就应该把每一层的偏导都求出来.然而\(\mathcal{ L }\)是最后一层的结果,因此应该用链式法则一路求出前面的偏导.

更具体地,不妨设误差函数选的是\(( \vec{ a } - \vec{ y } )^2\),激活函数选的是cross entropy有:

  1. \(\frac{ \partial{ \mathcal{ L } } }{ \partial \vec{ a }_{ L } } = ( \vec{ a }_{ L } - \vec{ y } )\).(如若选择不同的误差函数,这里作适当变化)

  2. \(\frac{ \partial \vec{ a }_{ l } }{ \partial \vec{ z }_{ l } } = f ' ( \vec{ z }_{ l } ) = \vec{ a }_{ l } \circ ( 1 - \vec{ a }_{ l } )\).(如若选取不同的激活函数,这里作适当变化)

  3. \(\frac{ \partial \vec{ z }_{ l + 1 } }{ \partial \vec{ z }_{ l } } = \frac{ \partial \vec{ z }_{ l + 1 } }{ \partial \vec{ a }_{ l } } \frac{ \partial \vec{ a }_{ l } }{ \partial \vec{ z }_{ l } } = ( W_{ l + 1 } )^t \times ( \vec{ a }_l \circ ( 1 - \vec{ a }_l ) )\).

  4. \(\frac{ \partial \vec{ z }_{ l } }{ \partial W_{ l } } = ( \vec{ a }_{ l - 1 } )\).结果理应是一个矩阵,其实就是这个列向量不断复制若干遍,或者写成\(( \vec{ a }_{ l - 1 } )^t M ( 1 )\),其中\(M ( 1 )\)是全\(1\)矩阵.

  5. \(\frac{ \partial \vec{ z }_{ l } }{ \partial \vec{ b }_{ l } } = 1\).

我们应当见到:

不妨设\(\delta_l = \frac{ \partial{ \mathcal{ L } } }{ \partial \vec{ z }_l }\).见到:

  1. \(\delta_L = \frac{ \partial \mathcal{ L } }{ \partial \vec{ z }_L } = \frac{ \partial \mathcal{ L } }{ \partial \vec{ a }_L } \frac{ \partial \vec{ a }_L }{ \partial \vec{ z }_L } = ( \vec{ a }_{ L } - \vec{ y } ) \circ \vec{ a }_{ L } \circ ( 1 - \vec{ a }_{ L } )\).前者会因为误差函数的选取而改变,后者会因为激活函数的选取而改变.

  2. \(\delta_l = \frac{ \partial{ \mathcal{ L } } }{ \partial \vec{ z }_l } = \delta_{ l + 1 } \frac{ \partial \vec{ z }_{ l + 1 } }{ \partial \vec{ z }_l } = \delta_{ l + 1 } \circ ( W_{ l + 1 } )^t \times ( \vec{ a }_{ l } \circ ( 1 - \vec{ a }_{ l } ) )\).

  3. \(\frac{ \partial \mathcal{ L } }{ \partial W_{ l } } = \frac{ \partial \mathcal{ L } }{ \partial \vec{ z }_{ l } } \frac{ \partial \vec{ z }_l }{ \partial W_{ l } } = \delta_l \times a_{ l - 1 }^t\).

  4. \(\frac{ \partial \mathcal{ L } }{ \partial \vec{ b }_l } = \delta_l\).

如此以上更新即可.

卷积神经网络(CNN)

神经网络受矩阵乘法的限制,导致对于真实的尺寸巨大的图像难以快速识别,因此产生了卷积神经网络的概念,大概有以下特征:

  1. 空间上权值共享:不同位置使用同一个卷积核(滤波器)

  2. 稀疏链接:每一层只链接前一层的感受野.

  3. 等变表示:卷积神经网络有某种平移不变性.

对于2D卷积,其公式如下:

\[ S_{ r , c } = ( X * W )_{ r , c } = \sum_i \sum_j X_{ r + i , c + j } \times w_{ i , j } \]

其中\(W\)是卷积核,\(X\)是输入图像,\(S\)是输出的结果.如果一个图像有多个通道(比如色彩层之类的),每个通道上都需要应用一个卷积核.

下面引入一些名词:

  1. input size:输入图像的尺寸.

  2. padding:填充的像素数.

  3. filter size:卷积核的尺寸.有时也写作两个变量:filter height和filter width.3D卷积还会有一个filter depth的变量.

  4. stride:步长.

  5. output size:卷积后输出的尺寸.有时也写作feature size.

  6. input channels:输入图像的通道数.

  7. n filters:卷积核的数量.

  8. dilation rate:膨胀率,用于空洞卷积.膨胀率为\(d\)的时候,卷积核中间会插入\(d - 1\)\(0\)间隔.

感受野计算

先看output size的计算,容易见到,其各个维度方面计算是独立的.只要对于单个维度算出卷积核在上面移动的次数,最后将不同维度相乘即可.

对于单个维度,这个维度的移动次数应该是:

$$ \[\begin{aligned} \text{ output \_ size } & = \lceil \frac{ \text{ input \_ size } + 2 \times \text{ padding } - \text{ filter \_ size } + 1 }{ \text{ stride } } \rceil \\ & = \lfloor \frac{ \text{ input \_ size } + 2 \times \text{ padding } - \text{ filter \_ size } }{ \text{ stride } } \rfloor + 1 \\ \end{aligned}\]

$$

这个公式相当容易理解,原因是\(\text{ stride } = 1\)的时候,上面恰好是移动的次数,而\(\text{ stride }\)变化的时候,当然要拿到一个上取整.

至于所谓的空洞卷积,只需在上面的基础上改\(\text{ filter \_ size }\)就好.

至于乘法操作,每得到一个\(\text{ output }\)当然都会需要\(\text{ filter \_ size }\)次乘法操作.

再看感受野的计算,不妨设\(S_i\)为前\(i\)次卷积的\(\text{ stride }\)的乘积,设\(k_{ i + 1 }\)表示第\(i + 1\)层的\(\text{ kernel \_ size }\),则:

\[ RF_{ i + 1 } = RF_i + ( k_{ i + 1 } - 1 ) \times S_i \]

这个公式的含义大概是每次先看对应了多大的原数据上的范围,再把原本的边界\(RF_i\)给补上.

池化(Pooling)

池化操作它没有一个可学习的参数,只是对输入数据进行固定的操作.简单来说就是降低输入的规模,以实现更好的鲁棒性以及提高效率.

常见的池化操作包括:

  1. MaxPooling:取区域内的最大值.

  2. MeanPooling:取区域内的平均值.

  3. PyramidPooling:多次进行尺度不同的池化.

常见卷积架构

AlexNet

首次引入ReLU激活函数,Dropout 技术,以及数据增强,提高了模型的训练效率和泛化能力.

采用了\(8\)层深的网络结构,证明了深度网络的潜力.

VGG

开始堆叠小尺寸的卷积核,获得与大卷积核相似的感受野的同时可以增加网络深度.

ResNet

引入残差的概念,直接将输入数据累加(跳跃连接)到最后的输出中,这样网络学习的实际上是输入和输出之间的残差,从而提高了网络学习能力.

SqueezeNet

SqueezeNet的基本构建单元是Fire模块.Fire模块由一个squeeze层和一个expand层组成.squeeze层使用\(1 \times 1\)卷积核减少通道数,而expand层则使用\(1 \times 1\)\(3 \times 3\)卷积核增加通道数.这种设计有效地减少了参数数量和计算量.

MobileNet
  1. 深度卷积:在这个操作中,每个输入通道独立地进行卷积,这意味着在进行卷积时,不同通道之间没有交互.这样可以减少计算量和参数数量.

  2. 逐点卷积:逐点卷积使用\(1 \times 1\)的卷积核,它作用在深度卷积的输出上,将不同通道的信息整合在一起.逐点卷积可以减少参数数量,同时保持较高的性能.

ShuffleNet
  1. 组卷积(Group Convolution):将通道分成几个组,并使用不同的卷积神经网络层执行标准卷积.

  2. 打乱层(Shuffle layer):通过对通道进行洗牌,将不同组的信息合并.

反卷积

也就是将较小的数据特征图扩大到较大的尺寸.有的时候也把这个操作说成上采样.

  1. 插值步骤(Interpolation Step):首先,在输入特征图的元素之间插入零,增加特征图的尺寸.

  2. 卷积步骤(Convolution Step):接下来,对扩大后的特征图应用一个标准的卷积操作.此步骤相当于在扩大的特征图上滑动卷积核,计算卷积输出.

0%