写在前面#
重新进行了排版,现在阳间多了。
数论相关#
莫比乌斯反演#
简单题在莫比乌斯反演学习笔记 里面。
被神仙虐了,来补几道休闲题。
题意:求 n ∑ i = 1 m ∑ j = 1 σ 1 ( gcd ( i , j ) ) [ gcd ( i , j ) ≤ a ] ∑ i = 1 n ∑ j = 1 m σ 1 ( gcd ( i , j ) ) [ gcd ( i , j ) ≤ a ]
做法:
不妨设 n ≤ m n ≤ m
n ∑ i = 1 m ∑ j = 1 σ 1 ( gcd ( i , j ) ) = n ∑ d = 1 ⌊ n d ⌋ ∑ i = 1 ⌊ m d ⌋ ∑ j = 1 σ 1 ( d ) [ gcd ( i , j ) = 1 ] = n ∑ d = 1 σ 1 ( d ) ⌊ n d ⌋ ∑ i = 1 ⌊ m d ⌋ ∑ j = 1 ∑ p ∣ i , p ∣ j μ ( p ) 这 步 把 gcd 扔 到 外 面 , 然 后 后 面 莫 反 = n ∑ d = 1 σ 1 ( d ) n ∑ p = 1 μ ( p ) ⌊ n d p ⌋ ⌊ m d p ⌋ 把 p 扔 到 外 面 , 枚 举 p = n ∑ t = 1 ⌊ n t ⌋ ⌊ m t ⌋ ∑ d ∣ t σ 1 ( d ) μ ( t d ) 令 t=dp ∑ i = 1 n ∑ j = 1 m σ 1 ( gcd ( i , j ) ) = ∑ d = 1 n ∑ i = 1 ⌊ n d ⌋ ∑ j = 1 ⌊ m d ⌋ σ 1 ( d ) [ gcd ( i , j ) = 1 ] = ∑ d = 1 n σ 1 ( d ) ∑ i = 1 ⌊ n d ⌋ ∑ j = 1 ⌊ m d ⌋ ∑ p ∣ i , p ∣ j μ ( p ) 这步把 gcd 扔到外面,然后后面莫反 = ∑ d = 1 n σ 1 ( d ) ∑ p = 1 n μ ( p ) ⌊ n d p ⌋ ⌊ m d p ⌋ 把 p 扔到外面,枚举 p = ∑ t = 1 n ⌊ n t ⌋ ⌊ m t ⌋ ∑ d ∣ t σ 1 ( d ) μ ( t d ) 令 t=dp
然后如果没有限制这题就没了,直接线性筛算前缀和然后整除分块即可。
问题是这玩意带个 [ gcd ( i , j ) ≤ a ] [ gcd ( i , j ) ≤ a ] ,咋做?
我们设: f ( t ) = ∑ d ∣ t σ 1 ( d ) μ ( t d ) f ( t ) = ∑ d ∣ t σ 1 ( d ) μ ( t d ) ,然后我们发现当 σ 1 ( d ) ≤ a σ 1 ( d ) ≤ a 的时候它才对答案贡献。于是我们将所有询问的 a a 从小到大排序,询问的时候每次会多出一些 d d 对 f ( t ) f ( t ) 做贡献。由于整除分块需要对 f f 进行区间查询,于是可以使用最好写的树状数组,每次枚举这一轮贡献的 d d 的每个倍数并且单点修改即可。
复杂度 O ( q √ n log n + n log 2 n ) O ( q n log n + n log 2 n ) ,左边是整除分块,右边是处理贡献。
题意:求 n ∏ i = 1 m ∏ j = 1 f gcd ( i , j ) ∏ i = 1 n ∏ j = 1 m f gcd ( i , j ) ,f f 为斐波那契数列。
做法:
套路枚举 gcd : gcd :
n ∏ i = 1 m ∏ j = 1 f gcd ( i , j ) = n ∏ d = 1 f ∑ n / d i = 1 ∑ m / d j = 1 [ gcd ( i , j ) = 1 ] d = n ∏ d = 1 f ∑ n / d i = 1 μ ( i ) ( n / i d ) ( m / i d ) d ∏ i = 1 n ∏ j = 1 m f gcd ( i , j ) = ∏ d = 1 n f d ∑ i = 1 n / d ∑ j = 1 m / d [ gcd ( i , j ) = 1 ] = ∏ d = 1 n f d ∑ i = 1 n / d μ ( i ) ( n / i d ) ( m / i d )
和上一题一样,令 t = i d : t = i d :
n ∏ d = 1 f ∑ n / d i = 1 μ ( i ) ( n / i d ) ( m / i d ) d = n ∏ t = 1 ∏ d ∣ t f μ ( t / d ) ( n / t ) ( m / t ) d = n ∏ t = 1 ⎛ ⎝ ∏ d ∣ t f μ ( t / d ) d ⎞ ⎠ ( n / t ) ( m / t ) ∏ d = 1 n f d ∑ i = 1 n / d μ ( i ) ( n / i d ) ( m / i d ) = ∏ t = 1 n ∏ d ∣ t f d μ ( t / d ) ( n / t ) ( m / t ) = ∏ t = 1 n ( ∏ d ∣ t f d μ ( t / d ) ) ( n / t ) ( m / t )
外面的 ( n / t ) ( m / t ) ( n / t ) ( m / t ) 告诉我们可以整除分块,考虑里面这玩意咋算。
同上一题,对于每个 d d ,我们枚举它的倍数,乘上 d d 的贡献即可计算,最后分块的时候搞一个前缀积即可。
令 p p 为模数,预处理 μ μ 和 f i b f i b 的复杂度暂且忽略不计,预处理斐波那契逆元的复杂度为 O ( n log p ) O ( n log p ) ,算贡献的部分由于是枚举倍数,所以是一个调和级数,即 O ( n log n ) O ( n log n ) ,整除分块复杂度为 O ( q √ n log p ) O ( q n log p ) (因为前缀积还原还要计算逆元)。
所以总复杂度为 O ( n log n + n log p + q √ n log p ) O ( n log n + n log p + q n log p ) ,大致算了一下大概是 6.36 × 10 7 6.36 × 10 7 ,时限充裕。
容斥/反演相关#
集合反演#
f ( S ) = ∑ T ⊆ S g ( T ) f ( S ) = ∑ T ⊆ S g ( T )
g ( S ) = ∑ T ⊆ S ( − 1 ) | S | − | T | f ( T ) g ( S ) = ∑ T ⊆ S ( − 1 ) | S | − | T | f ( T )
或者
f ( S ) = ∑ S ⊆ T g ( T ) f ( S ) = ∑ S ⊆ T g ( T )
g ( S ) = ∑ S ⊆ T ( − 1 ) | T | − | S | f ( T ) g ( S ) = ∑ S ⊆ T ( − 1 ) | T | − | S | f ( T )
CF1770F Koxia and Sequence#
给定非负整数 n , x , y n , x , y ,对于所有满足 n ∑ i = 1 a i = x ∑ i = 1 n a i = x 并且 OR n i = 1 a i = y OR i = 1 n a i = y 的 { a n } { a n } ,求 n ⨁ i = 1 a i ⨁ i = 1 n a i 的异或和。
n ≤ 2 40 , x ≤ 2 60 , y ≤ 2 20 n ≤ 2 40 , x ≤ 2 60 , y ≤ 2 20 。
首先根据对称性,当 n n 为偶数时,答案为 0 0 。所以只考虑 n n 为奇数的情况,为 a 1 a 1 的异或和。
拆位,对每一位 t t ,计算 a 1 a 1 的第 t t 位为 1 1 的方案数 mod 2 mod 2 的结果。此时显然 n ⨁ i = 1 a i ⨁ i = 1 n a i 第 t t 位为 1 1 。
考虑容斥,设 g ( y ) g ( y ) 为按位或为 y y 的方案数,f ( y ) f ( y ) 为按位或为 y y 的子集的方案数,显然 f ( y ) = ∑ y ′ ⊆ y g ( y ′ ) f ( y ) = ∑ y ′ ⊆ y g ( y ′ ) ,反演结论得到 g ( y ) = ∑ y ′ ⊆ y ( − 1 ) | y | − | y ′ | f ( y ′ ) g ( y ) = ∑ y ′ ⊆ y ( − 1 ) | y | − | y ′ | f ( y ′ ) ,前提是 y ′ y ′ 第 t t 位为 1 1 。
由于我们只需要得到 g ( y ) g ( y ) 的奇偶性,所以我们可以将式子变为 g ( y ) ≡ ⨁ y ′ ⊆ y f ( y ′ ) mod 2 g ( y ) ≡ ⨁ y ′ ⊆ y f ( y ′ ) mod 2 。
因为钦定 a 1 a 1 的第 t t 位为 1 1 ,我们可以让 a 1 a 1 减去 2 t 2 t ,此时 n ∑ i = 1 a i = x − 2 t ∑ i = 1 n a i = x − 2 t 。 由 Lucas Lucas 定理推论(组合数奇偶性定理)与 Vandermonde Vandermonde 卷积公式得:
f ( y ) = ∑ ∑ a i = x − 2 t [ a 1 ⊆ y − 2 t ] [ a 2 ⊆ y ] [ a 3 ⊆ y ] . . . [ a n ⊆ y ] ≡ ∑ ∑ a i = x − 2 t ( y − 2 t a 1 ) ( y a 2 ) ( y a 3 ) . . . ( y a n ) mod 2 ≡ ( n y − 2 t x − 2 t ) mod 2 ≡ [ x − 2 t ⊆ n y − 2 t ] mod 2 f ( y ) = ∑ ∑ a i = x − 2 t [ a 1 ⊆ y − 2 t ] [ a 2 ⊆ y ] [ a 3 ⊆ y ] . . . [ a n ⊆ y ] ≡ ∑ ∑ a i = x − 2 t ( y − 2 t a 1 ) ( y a 2 ) ( y a 3 ) . . . ( y a n ) mod 2 ≡ ( n y − 2 t x − 2 t ) mod 2 ≡ [ x − 2 t ⊆ n y − 2 t ] mod 2
所以答案即为:
∑ t 2 t f ( y ) = ∑ t 2 t ⨁ y ′ ⊆ y , 2 t ∈ y ′ g ( y ′ ) = ∑ t 2 t ⨁ y ′ ⊆ y , 2 t ∈ y ′ [ x − 2 t ⊆ n y − 2 t ] ∑ t 2 t f ( y ) = ∑ t 2 t ⨁ y ′ ⊆ y , 2 t ∈ y ′ g ( y ′ ) = ∑ t 2 t ⨁ y ′ ⊆ y , 2 t ∈ y ′ [ x − 2 t ⊆ n y − 2 t ]
O ( y log y ) O ( y log y ) 枚举 t , y ′ t , y ′ 即可。
SHOI2016 黑暗前的幻想乡#
n n 个点,n − 1 n − 1 种颜色。每种颜色有 m i m i 条边连接 u j , v j u j , v j 两个节点。求颜色数为 n − 1 n − 1 的生成树数量。
n ≤ 17 n ≤ 17 。
实在不会一些不太板的数数题……
考虑以颜色为集合状态,令 f S f S 为恰有 S S 中颜色的生成树数量,g S g S 为颜色在 S S 中的生成树数量。
显然有 g S = ∑ T ⊆ S f T g S = ∑ T ⊆ S f T 。那么 f S = ∑ T ⊆ S ( − 1 ) | S | − | T | g T f S = ∑ T ⊆ S ( − 1 ) | S | − | T | g T 。
所以答案就是 f U = ∑ T ( − 1 ) n − 1 − | T | g T f U = ∑ T ( − 1 ) n − 1 − | T | g T ,枚举 T T 然后把 T T 所有颜色拉出来求无向图生成树个数即可。
可以 matrix\ tree matrix\ tree 定理。复杂度 O ( 2 n n 3 ) O ( 2 n n 3 ) 。
二项式反演#
这个形式有点多,最常用的:
f ( n ) = n ∑ i = 0 ( n i ) g ( i ) f ( n ) = ∑ i = 0 n ( n i ) g ( i )
g ( n ) = n ∑ i = 0 ( − 1 ) n − i ( n i ) f ( i ) g ( n ) = ∑ i = 0 n ( − 1 ) n − i ( n i ) f ( i )
不太常用的:
f ( n ) = n ∑ i = 0 ( − 1 ) i ( n i ) g ( i ) f ( n ) = ∑ i = 0 n ( − 1 ) i ( n i ) g ( i )
g ( n ) = n ∑ i = 0 ( − 1 ) i ( n i ) f ( i ) g ( n ) = ∑ i = 0 n ( − 1 ) i ( n i ) f ( i )
这主要告诉我们 A i i = ( − 1 ) i ( n i ) A i i = ( − 1 ) i ( n i ) 这个矩阵是自逆 的。
例题有点板。我数学怎么这么菜。
莫比乌斯反演#
形式 1 1 (约数形式):
f ( n ) = ∑ d ∣ n g ( d ) f ( n ) = ∑ d ∣ n g ( d )
g ( n ) = ∑ d ∣ n μ ( d ) f ( n d ) g ( n ) = ∑ d ∣ n μ ( d ) f ( n d )
这是显然的,由 f = g ∗ I , μ = I − 1 f = g ∗ I , μ = I − 1 可推出 g = f ∗ μ g = f ∗ μ 。
形式 2 2 (倍数形式):
f ( n ) = ∑ n ∣ d g ( d ) f ( n ) = ∑ n ∣ d g ( d )
g ( n ) = ∑ n ∣ d μ ( d n ) f ( d ) g ( n ) = ∑ n ∣ d μ ( d n ) f ( d )
这鬼东西有点抽象,找时间补个证明。
一般用于解决数论问题,找不到什么高妙不板的例题。
下面是科技。
Min-Max 容斥#
对于满足全序关系并且其中元素满足可加减性的可重 集合 S S ,有:
max { S } = ∑ T ⊆ S ( − 1 ) | T | − 1 min { T } max { S } = ∑ T ⊆ S ( − 1 ) | T | − 1 min { T }
min { S } = ∑ T ⊆ S ( − 1 ) | T | − 1 max { T } min { S } = ∑ T ⊆ S ( − 1 ) | T | − 1 max { T }
证明(参考 OI Wiki
):
考虑构造映射 f : S k → { 1 , 2 , . . . , k } f : S k → { 1 , 2 , . . . , k } ,S k S k 为 S S 中第 k k 大元素,显然这是双射。
那么 f ( min ( x , y ) ) = f ( x ) ∩ f ( y ) , f ( max ( x , y ) ) = f ( x ) ∪ f ( y ) f ( min ( x , y ) ) = f ( x ) ∩ f ( y ) , f ( max ( x , y ) ) = f ( x ) ∪ f ( y ) 。
所以:
| f ( max { S } ) | = ∣ ∣ ⋃ t ∈ S f ( t ) ∣ ∣ = ∑ T ⊆ S ( − 1 ) | T | − 1 ∣ ∣ ⋂ t ∈ T f ( t ) ∣ ∣ = ∑ T ⊆ S ( − 1 ) | T | − 1 | f ( min { T } ) | | f ( max { S } ) | = | ⋃ t ∈ S f ( t ) | = ∑ T ⊆ S ( − 1 ) | T | − 1 | ⋂ t ∈ T f ( t ) | = ∑ T ⊆ S ( − 1 ) | T | − 1 | f ( min { T } ) |
两边的 f f 都可以映射回去,用类似的证法可以把左式换成最小值,所以 Min-Max Min-Max 容斥成立。
事实上,Min-Max Min-Max 容斥也可以作用于期望:
E ( max { S } ) = ∑ T ⊆ S ( − 1 ) | T | − 1 E ( min { T } ) E ( max { S } ) = ∑ T ⊆ S ( − 1 ) | T | − 1 E ( min { T } )
E ( min { S } ) = ∑ T ⊆ S ( − 1 ) | T | − 1 E ( max { T } ) E ( min { S } ) = ∑ T ⊆ S ( − 1 ) | T | − 1 E ( max { T } )
证明可以考虑期望的定义式,注意 S 0 S 0 代表 S S 所有可能出现元素 的并:
E ( max { S } ) = ∑ S ′ ⊆ S 0 P ( S ′ = S ) max { S ′ } = ∑ S ′ ⊆ S 0 P ( S ′ = S ) ∑ T ⊆ S ′ ( − 1 ) | T | − 1 min { T } = ∑ T ⊆ S 0 ( − 1 ) | T | − 1 ∑ T ⊆ S ′ P ( S ′ = S ) min { T } = ∑ T ⊆ S 0 ( − 1 ) | T | − 1 E ( min ( T ) ) E ( max { S } ) = ∑ S ′ ⊆ S 0 P ( S ′ = S ) max { S ′ } = ∑ S ′ ⊆ S 0 P ( S ′ = S ) ∑ T ⊆ S ′ ( − 1 ) | T | − 1 min { T } = ∑ T ⊆ S 0 ( − 1 ) | T | − 1 ∑ T ⊆ S ′ P ( S ′ = S ) min { T } = ∑ T ⊆ S 0 ( − 1 ) | T | − 1 E ( min ( T ) )
需要注意的是倒数第二行 ∑ T ⊆ S ′ P ( S ′ = S ) min { T } ∑ T ⊆ S ′ P ( S ′ = S ) min { T } 中即使 S ′ S ′ 带附加条件,这个式子仍然表示的是 T T 的期望最小值,理由可以自行思考(
HAOI2015 按位或#
刚开始你有一个数字 0 0 ,每一秒钟你会随机选择一个 [ 0 , 2 n − 1 ] [ 0 , 2 n − 1 ] 的数字,与你手上的数字进行或(C++,C 的 |
,pascal 的 or
)操作。选择数字 i i 的概率是 p i p i 。保证 0 ≤ p i ≤ 1 0 ≤ p i ≤ 1 ,∑ p i = 1 ∑ p i = 1 。问期望多少秒后,你手上的数字变成 2 n − 1 2 n − 1 。
n ≤ 20 n ≤ 20 。
根据 Min-Max Min-Max 容斥原理:
E ( max { S } ) = ∑ T ⊆ S ( − 1 ) | T | − 1 E ( min { T } ) E ( max { S } ) = ∑ T ⊆ S ( − 1 ) | T | − 1 E ( min { T } )
本题中 S S 代表一个位数的集合,max { S } max { S } 为 S S 中元素最后一个变为 1 1 的时间,min { T } min { T } 为 T T 中元素第一个变为 1 1 的时间,显然答案就是左式 E ( m a x { S } ) E ( m a x { S } ) 。
考虑求解 E ( min { T } ) E ( min { T } ) ,由于 T T 中至少有一个元素变为 1 1 的概率为 ∑ T ′ ∩ T ≠ ∅ P T ′ ∑ T ′ ∩ T ≠ ∅ P T ′ ,根据期望的定义我们知道 E ( min { T } ) = 1 ∑ T ′ ∩ T ≠ ∅ P T ′ E ( min { T } ) = 1 ∑ T ′ ∩ T ≠ ∅ P T ′ ,其中 U U 表示全集 { 0 , 1 , . . . , n − 1 } { 0 , 1 , . . . , n − 1 } 。
这个有交的东西比较难搞,正难则反,考虑 U U 的补集,则 E ( min { T } ) = 1 ∑ T ′ ∩ T ≠ ∅ P T ′ = 1 1 − ∑ T ′ ⊆ U ∖ T P T ′ E ( min { T } ) = 1 ∑ T ′ ∩ T ≠ ∅ P T ′ = 1 1 − ∑ T ′ ⊆ U ∖ T P T ′ 。
于是问题变为求解 ∑ T ′ ⊆ T P T ′ ∑ T ′ ⊆ T P T ′ ,这显然是一个 FWT
的或运算变换,直接 O ( n 2 n ) O ( n 2 n ) 做即可。
最后枚举每个 T T ,求其贡献即可,复杂度 O ( n 2 n ) O ( n 2 n ) 。
PKUWC2018 随机游走#
给定一棵 n n 个结点的树,你从点 x x 出发,每次等概率随机选择一条与所在点相邻的边走过去。
有 Q Q 次询问,每次询问给定一个集合 S S ,求如果从 x x 出发一直随机游走,直到点集 S S 中所有点都至少经过一次的话,期望游走几步。
特别地,点 x x (即起点)视为一开始就被经过了一次。
n ≤ 18 n ≤ 18 ,Q ≤ 5000 Q ≤ 5000 ,对 998244353 998244353 取模。
求集合内最大时间的期望,一眼 Min-Max Min-Max 容斥。
E ( max { S } ) = ∑ T ⊆ S ( − 1 ) | T | − 1 E ( min { T } ) E ( max { S } ) = ∑ T ⊆ S ( − 1 ) | T | − 1 E ( min { T } )
为什么我每题都要写一遍这个式子。
左式即为所求,考虑右式 E ( min { T } ) E ( min { T } ) 怎么做,它的意义为对于每一个 T ⊆ S T ⊆ S ,求出随机游走并第一次走到 u ∈ T u ∈ T 的期望时间。
对于随机游走问题,可以用 dp 解决。
设 f T , i f T , i 表示树上从 i i 游走到第一个 T T 中的点的期望时间。
那么显然:
f T , i = 0 , i ∈ T f T , i = 0 , i ∈ T
f T , i = 1 + 1 d e g i ∑ ( u , i ) ∈ E f T , u , otherwise f T , i = 1 + 1 d e g i ∑ ( u , i ) ∈ E f T , u , otherwise
应该注意的是这里状态转移之间包含了环,所以不能直接从下往上或从上往下递推。
对于这类随机游走问题,我们一般使用高斯消元 求解,但是这题使用高斯消元是 O ( n 3 ) O ( n 3 ) 的,预处理就需要 O ( 2 n n 3 log w ) O ( 2 n n 3 log w ) ,显然超时。但是树上随机游走问题我们有一些特殊的技巧。
为了简化算式,以下 f T , i f T , i 简记为 f i f i ,读者需要知道这是对于每一个 T T 而言 的。
首先考虑叶子节点 u u ,显然它能够被表示成 A u + B u × f f a u A u + B u × f f a u 的形式:如果 u ∈ T u ∈ T ,那么 A u = B u = 0 A u = B u = 0 ,否则 A u = B u = 1 A u = B u = 1 。
然后我们考虑归纳,假设节点 u u 的所有儿子 v 1 , v 2 , . . . , v m v 1 , v 2 , . . . , v m 均可以表示成 A v i + B v i × f u A v i + B v i × f u 的形式,那么对于节点 u u :
显然存在 A u = B u = 0 A u = B u = 0 使得 f u = 0 f u = 0 ,u ∈ T u ∈ T
若 u ∉ T u ∉ T ,则:
f u = 1 + 1 d e g u ( f f a u + m ∑ i = 1 A v i + B v i × f u ) f u = 1 + 1 d e g u ( f f a u + ∑ i = 1 m A v i + B v i × f u )
那就解一个方程即可:
f u = d e g u + m ∑ i = 1 A v i d e g u − m ∑ i = 1 B v i + f f a u d e g u − m ∑ i = 1 B v i f u = d e g u + ∑ i = 1 m A v i d e g u − ∑ i = 1 m B v i + f f a u d e g u − ∑ i = 1 m B v i
令 A u = d e g u + m ∑ i = 1 A v i d e g u − m ∑ i = 1 B v i A u = d e g u + ∑ i = 1 m A v i d e g u − ∑ i = 1 m B v i ,B u = 1 d e g u − m ∑ i = 1 B v i B u = 1 d e g u − ∑ i = 1 m B v i 即可满足 f u = A u + B u × f f a u f u = A u + B u × f f a u 。
那么我们令 x x 作为根,从儿子向根递推能得到每个点的 A u , B u A u , B u ,由于 x x 没有父亲,那么 f T , x = A x f T , x = A x ,我们就能 O ( 2 n n log w ) O ( 2 n n log w ) 得到对于每一个 T T ,E ( min { T } ) E ( min { T } ) 的值,记为 g T g T 。
那么对于每一个 S S ,我们只需要求 ∑ T ⊆ S ( − 1 ) | T | − 1 g T ∑ T ⊆ S ( − 1 ) | T | − 1 g T ,跑 FWT
或变换即可。
拓展 Min-Max 容斥#
由于我被神仙 sinsop90
踩爆了,所以添加一点内容。
事实上,Min-Max Min-Max 容斥可以求出第 k k 大小:
max k { S } = ∑ T ⊆ S ( − 1 ) | T | − k ( | T | − 1 k − 1 ) min { T } max k { S } = ∑ T ⊆ S ( − 1 ) | T | − k ( | T | − 1 k − 1 ) min { T }
min k { S } = ∑ T ⊆ S ( − 1 ) | T | − k ( | T | − 1 k − 1 ) max { T } min k { S } = ∑ T ⊆ S ( − 1 ) | T | − k ( | T | − 1 k − 1 ) max { T }
E ( max k { S } ) = ∑ T ⊆ S ( − 1 ) | T | − k ( | T | − 1 k − 1 ) E ( min { T } ) E ( max k { S } ) = ∑ T ⊆ S ( − 1 ) | T | − k ( | T | − 1 k − 1 ) E ( min { T } )
E ( min k { S } ) = ∑ T ⊆ S ( − 1 ) | T | − k ( | T | − 1 k − 1 ) E ( max { T } ) E ( min k { S } ) = ∑ T ⊆ S ( − 1 ) | T | − k ( | T | − 1 k − 1 ) E ( max { T } )
证明略。
P4707 重返现世#
有 n n 种原料,需要集齐任意 k k 种。
每个单位时间会随机生成一种原料。每种原料被生成的概率是不同的,第 i i 种原料被生成的概率是 p i m p i m 。
求收集到任意 k k 种原料的期望时间,答案对 998244353 998244353 取模。
n ≤ 10 3 , | n − k | ≤ 10 , m ≤ 10 4 n ≤ 10 3 , | n − k | ≤ 10 , m ≤ 10 4 。
我们可以把题目看作每个原料有一个生成时间,即求第 n − k + 1 n − k + 1 大的期望值。为了简化式子,以下令 k ← n − k + 1 k ← n − k + 1 ,显然 k ≤ 11 k ≤ 11 ,并且求的是第 k k 大的期望。
套用拓展 Min-Max Min-Max 容斥,把前 k k 大转换成最小:
E ( max k ( S ) ) = ∑ T ⊆ S ( | T | − 1 k − 1 ) ( − 1 ) | T | − k E ( min ( T ) ) E ( max k ( S ) ) = ∑ T ⊆ S ( | T | − 1 k − 1 ) ( − 1 ) | T | − k E ( min ( T ) )
显然对于每一种 T T ,可以把 T T 中的原料看成一类,其它的看作另一类,那么抽到 T T 中原料的概率显然就是 P T = ∑ i ∈ T p i m P T = ∑ i ∈ T p i m ,由于E ( min ( T ) ) E ( min ( T ) ) 表示第一次抽到 T T 中原料的期望时间,所以由简单期望知识我们知道 E ( min ( T ) ) = 1 P T = m ∑ i ∈ T p i E ( min ( T ) ) = 1 P T = m ∑ i ∈ T p i 。
所以
a n s k = ∑ T ⊆ S ( | T | − 1 k − 1 ) ( − 1 ) | T | − k m ∑ i ∈ T p i = m ∑ T ⊆ S ( | T | − 1 k − 1 ) ( − 1 ) | T | − k ∑ i ∈ T p i a n s k = ∑ T ⊆ S ( | T | − 1 k − 1 ) ( − 1 ) | T | − k m ∑ i ∈ T p i = m ∑ T ⊆ S ( | T | − 1 k − 1 ) ( − 1 ) | T | − k ∑ i ∈ T p i
然后考虑 d p d p ,由于 k k 、m m 都很小,于是可以纳入状态,令 d p i , j , k d p i , j , k 表示当前考虑前 i i 种原料,∑ i ∈ T p i = j ∑ i ∈ T p i = j 的时候 ∑ T ⊆ S ( | T | − 1 k − 1 ) ( − 1 ) | T | − k ∑ T ⊆ S ( | T | − 1 k − 1 ) ( − 1 ) | T | − k 的值。
转移的话,其实非常显然。
首先你可以不取 i i ,d p i , j , k ← d p i − 1 , j , k d p i , j , k ← d p i − 1 , j , k 。
其次,如果你选了 i i ,那么:
( | T | − 1 k − 1 ) ( − 1 ) | T | − k = ( | T | − 2 k − 2 ) ( − 1 ) ( | T | − 2 ) − ( k − 2 ) − ( | T | − 2 k − 1 ) ( − 1 ) ( | T | − 2 ) − ( k − 1 ) ( | T | − 1 k − 1 ) ( − 1 ) | T | − k = ( | T | − 2 k − 2 ) ( − 1 ) ( | T | − 2 ) − ( k − 2 ) − ( | T | − 2 k − 1 ) ( − 1 ) ( | T | − 2 ) − ( k − 1 )
于是这种情况可以从 d p i − 1 , j − p i , k d p i − 1 , j − p i , k 与 d p i − 1 , j − p i , k − 1 d p i − 1 , j − p i , k − 1 转移过来。
总的转移式子就是:
d p i , j , k = d p i − 1 , j , k + d p i − 1 , j − p i , k − 1 − d p i − 1 , j − p i , k d p i , j , k = d p i − 1 , j , k + d p i − 1 , j − p i , k − 1 − d p i − 1 , j − p i , k
O ( n m k ) O ( n m k ) 转移即可,但是注意边界 d p 0 , 0 , 0 = 0 , d p 0 , 0 , i = − 1 ( i > 0 ) d p 0 , 0 , 0 = 0 , d p 0 , 0 , i = − 1 ( i > 0 ) 。
单位根反演#
[ n ∣ k ] = 1 n n − 1 ∑ d = 0 ω i k n [ n ∣ k ] = 1 n ∑ d = 0 n − 1 ω n i k
这个东西没啥用,但是:
单位根反演常用于求某个多项式特定倍数的系数和。
⌊ n k ⌋ ∑ i = 0 [ x i k ] f ( x ) = n ∑ i = 0 [ k ∣ i ] [ x i ] f ( x ) = n ∑ i = 0 [ x i ] f ( x ) 1 k k − 1 ∑ j = 0 ω i j k = 1 k n ∑ i = 0 a i k − 1 ∑ j = 0 ω i j k = 1 k n ∑ i = 0 k − 1 ∑ j = 0 a i ( ω j k ) i = 1 k k − 1 ∑ j = 0 f ( ω j k ) ∑ i = 0 ⌊ n k ⌋ [ x i k ] f ( x ) = ∑ i = 0 n [ k ∣ i ] [ x i ] f ( x ) = ∑ i = 0 n [ x i ] f ( x ) 1 k ∑ j = 0 k − 1 ω k i j = 1 k ∑ i = 0 n a i ∑ j = 0 k − 1 ω k i j = 1 k ∑ i = 0 n ∑ j = 0 k − 1 a i ( ω k j ) i = 1 k ∑ j = 0 k − 1 f ( ω k j )
推论:
⌊ n k ⌋ ∑ i = 0 [ x i k + r ] f ( x ) = 1 k k − 1 ∑ j = 0 f ( ω j k ) ω − i r k ∑ i = 0 ⌊ n k ⌋ [ x i k + r ] f ( x ) = 1 k ∑ j = 0 k − 1 f ( ω k j ) ω k − i r
集合幂级数#
FWT | 快速沃尔什变换#
默认你已经会了模板题(求或、与、异或卷积)。
发现 m m 很小,所以一个箱子可以用一个二进制数 a i a i 表示,值域 w = 2 20 w = 2 20 。然后就变成取出若干个 a i a i 使得或起来为全集的方案数。
将所有 a i a i 按位取反,即求若干个 a i a i 与起来为空集的方案数,就是这题 。
考虑容斥,令 t S t S 为与起来恰为 S S 的方案数,g S g S 为与起来包含 S S 的方案数。显然有 g S = ∑ S ⊆ T t T g S = ∑ S ⊆ T t T ,反演得到 t S = ∑ S ⊆ T ( − 1 ) | S | − | T | g T t S = ∑ S ⊆ T ( − 1 ) | S | − | T | g T 。由于我们要求 t ∅ t ∅ ,即为 ∑ T ( − 1 ) | T | g T ∑ T ( − 1 ) | T | g T 。由于可以 O ( w ) O ( w ) 枚举 T T ,我们现在考虑如何求 g g 。
由于与起来包含 S S ,所以你选出来每个数都包含 S S ,所以 g S = 2 f S − 1 g S = 2 f S − 1 ,f S f S 为包含 S S 的数的个数。
显然 f f 是个超集和,想一下 FWT 求子集和的时候,把前面贡献后面,那么现在在后面贡献前面即可。
然后就做完了。复杂度 O ( n + w log w ) O ( n + w log w ) 。
FST | 子集卷积相关#
其实是暴力。
因为这是模板题,所以模板的前置知识也要讲。
这里只需要掌握快速计算或卷积的方法,所以内容较少。如果向了解更多(比如异或卷积)的话可以去 P4717 看看。
例题:给定长度为 2 n 2 n 的序列 a , b a , b ,求 c k = ∑ i | j = k a i b j c k = ∑ i | j = k a i b j 序列中每一项的值。我们需要一个 O ( n log n ) O ( n log n ) 的解法。
考虑根据 a , b a , b 构造两个序列 A , B A , B ,若 a → A , b → B a → A , b → B 均为 O ( n log n ) O ( n log n ) 并且这个过程可逆,令 C i = A i × B i C i = A i × B i ,若 C C 能还原回 c c ,那么我们就可以 O ( n log n ) O ( n log n ) 计算 c c 。
在这里,我们令 A i = ∑ j | i = i a j A i = ∑ j | i = i a j (也就是 j j 为 i i 的子集)。那么有 C i = ∑ ( j | k ) | i = i a j b k C i = ∑ ( j | k ) | i = i a j b k 。
那么有:
A i × B i = ⎛ ⎝ ∑ j | i = i a j ⎞ ⎠ ⎛ ⎝ ∑ j | i = i b j ⎞ ⎠ = ∑ j | i = i , k | i = i a j b k = ∑ ( j | k ) | i = i a j b k = C i A i × B i = ( ∑ j | i = i a j ) ( ∑ j | i = i b j ) = ∑ j | i = i , k | i = i a j b k = ∑ ( j | k ) | i = i a j b k = C i
也就是说我们证明了这个 A , B A , B 是的确能映射到一个正确的 C C 的。现在考虑如何快速求 A i = ∑ j | i a j A i = ∑ j | i a j 。
显然可以从低到高枚举每个二进制位,然后当前位为 0 0 的是右边对应位置为 1 1 的子集,从左依次贡献到右即可。
C → c C → c 相当于求一个逆过程,右边依次减去左边的贡献即可。
参考了这里 的代码。
void fwt (int *s, int op) {
op = (op + mod) % mod;
for (int o = 2 , k = 1 ; o <= S + 1 ; o <<= 1 , k <<= 1 )
for (int i = 0 ; i <= S; i += o)
for (int j = 0 ; j < k; j++)
(s[i + j + k] += 1ll * s[i + j] * op % mod) %= mod;
}
你发现这东西就多加了一个限制 i & j = 0 i & j = 0 ,也就是说 i , j i , j 无交。
考虑一个充要条件,i & j = 0 i & j = 0 并且 i | j = k i | j = k 其实就相当于 | i | + | j | = | k | | i | + | j | = | k | 并且 i | j = k i | j = k ,| i | | i | 表示 i i 集合的大小,即 i i 中 1 1 的个数。
所以可以预处理 f i , j f i , j 表示满足 | j | = i | j | = i 的 a j a j 的值,g i , j g i , j 对 b b 同理。
那么 c k = n ∑ i = 0 2 n ∑ j = 0 ∑ j | l = k f i , j g k − i , l c k = ∑ i = 0 n ∑ j = 0 2 n ∑ j | l = k f i , j g k − i , l 。
令 h i = n ∑ k = 0 f k ∗ g i − k h i = ∑ k = 0 n f k ∗ g i − k ,∗ ∗ 表示进行或卷积,那么 c i = h | i | , i c i = h | i | , i 。
FWT 预处理每个 f k f k 和 g k g k 的子集和,枚举这个 i , k i , k 求出 h h 的子集和,然后做逆的 FWT 就做完了。复杂度 O ( n log 2 n ) O ( n log 2 n ) 。
太神仙了。
直接子集卷积肯定是不行的,1s 的时限和 62MB 的空间摆在那里。
那就要考虑使用模 4 4 的性质乱搞了。
我们考虑给每个 i i ,不管它符不符合条件,赋一个权值。如果 i and j ≠ 0 i and j ≠ 0 ,它对答案是没有贡献的,否则它能贡献到 i or j i or j 的位置。
那考虑所有没贡献 ( i , j ) ( i , j ) ,我们想装模做样地给它贡献到 i or j i or j ,就需要 i i 和 j j 的权值“抵消”掉。下面是一个十分精妙的想法:
由于 i and j ≠ 0 i and j ≠ 0 ,那么 | i | + | j | ≥ | i or j | | i | + | j | ≥ | i or j | 。我们可以给每个 a i a i 赋为 a i × 4 popcount(i) a i × 4 popcount(i) ,b b 同理,我们计算 c k = ∑ i or j = k a i b j c k = ∑ i or j = k a i b j ,那么 c k c k 中 i and j i and j 不为 0 0 的项的乘积必然能被 4 popcount(k)+1 4 popcount(k)+1 整除,不做贡献,所以最后 c k c k 直接除 4 popcount(k) 4 popcount(k) 再模 4 4 就是正确的答案。
显然对于合法的 i , j i , j ,对 c k c k 的贡献按照上述方法计算,还是单次的。
然后就做完了,计算 c c 需要 FWT,所以复杂度 O ( n 2 n ) O ( n 2 n ) 。
太神仙了。
有一个显然的状压,设 f S f S 表示划分完城市集合 S S 之后的答案。
f S = ∑ T f ( S ∖ T ) ∑ i ∈ T w i ∑ i ∈ S w i f S = ∑ T f ( S ∖ T ) ∑ i ∈ T w i ∑ i ∈ S w i
要求 T T 中不包含欧拉回路。
显然可以 O ( n 2 n ) O ( n 2 n ) 预处理 g S = ∑ i ∈ S w i g S = ∑ i ∈ S w i ,要求 S S 合法:
f S = ∑ T f ( S ∖ T ) g T g S = 1 g S ∑ T f ( S ∖ T ) g T f S = ∑ T f ( S ∖ T ) g T g S = 1 g S ∑ T f ( S ∖ T ) g T
然后这是个显然的子集卷积,做完了,O ( n 2 2 n ) O ( n 2 2 n ) 。
考虑先手必胜的充要条件。
实际上,只要 n n 为奇数或者本质不同排列为偶数时先手必胜。
n n 为奇数时,先手必胜,答案就是 k n k n 。
n n 为偶数时,令 a i a i 为第 i i 个字符出现次数,k ∑ i = 1 a i = n ∑ i = 1 k a i = n 。反面考虑,我们相当于求 ( n a 1 a 2 . . . a k ) ( n a 1 a 2 . . . a k ) 为奇数的方案数。
根据 Lucas 定理 :
( m n ) ≡ q ∏ i = 0 ( m i n i ) mod p ( m n ) ≡ ∏ i = 0 q ( m i n i ) mod p
其中 m = q ∑ i = 0 p i m i m = ∑ i = 0 q p i m i ,n n 同理。
显然这里令 p p 为 2 2 ,m i , n i ∈ { 0 , 1 } m i , n i ∈ { 0 , 1 } 。这告诉我们 ( n a 1 a 2 . . . a k ) ( n a 1 a 2 . . . a k ) 为奇数,相当于 ∀ i ≠ j , a i & a j = 0 ∀ i ≠ j , a i & a j = 0 。
考虑一个 dp,f i , j f i , j 表示前考虑 i i 个字符,目前 ∑ a i ∑ a i 为 j j 的方案数。那么有转移方程:
f p , l = ∑ i & j = 0 , i | j = l f p − 1 , i 1 j ! f p , l = ∑ i & j = 0 , i | j = l f p − 1 , i 1 j !
这东西显然是个子集卷积,预处理 g | i | , i = 1 i ! g | i | , i = 1 i ! 的子集和,暴力 做 O ( k n log 2 n ) O ( k n log 2 n ) 。
然后你死了,最大的点跑了 13 秒,而且空间爆了。考虑优化。
我们考虑指数生成函数暴力 exp 取 ln 然后就做完了。
其实每次转移的 g g 都是相同的,这让我们想到了快速幂。
借用快速幂的思想,省略每次重复计算 f f 卷 g g 的若干次,复杂度 O ( n log 2 n log k ) O ( n log 2 n log k ) 。
挺卡常,但这总比多项式好吧。
组合计数#
斯特林数#
普通幂转下降幂:
n m = m ∑ i = 0 { m i } n i – n m = ∑ i = 0 m { m i } n i _
虽然我们家哥哥的房塌了……但这不影响我们卷题啊!
考虑枚举选出来 i i 个没气 的篮球,那么答案可以表示成:
ans = 1 ( n k ) k ∑ i = 0 ( m i ) ( n − m k − i ) i L ans = 1 ( n k ) ∑ i = 0 k ( m i ) ( n − m k − i ) i L
注意到这里的组合数 ( n m ) ( n m ) 在 n < m n < m 或者 m < 0 m < 0 时无意义,直接当成 0 0 即可。
考虑普通幂转下降幂:
i L = L ∑ j = 0 { L j } i j – i L = ∑ j = 0 L { L j } i j _
带入原式有:
ans = 1 ( m k ) k ∑ i = 0 ( m i ) ( n − m k − i ) L ∑ j = 0 { L j } i j – = 1 ( m k ) L ∑ j = 0 { L j } k ∑ i = 0 ( m i ) ( n − m k − i ) i j – ans = 1 ( m k ) ∑ i = 0 k ( m i ) ( n − m k − i ) ∑ j = 0 L { L j } i j _ = 1 ( m k ) ∑ j = 0 L { L j } ∑ i = 0 k ( m i ) ( n − m k − i ) i j _
根据经典组合恒等式:
( m i ) i j – = m ! i ! ( m − i ) ! ⋅ i ! ( i − j ) ! = m ! ( m − i ) ! ( i − j ) ! = ( m − j ) ! ( m − i ) ! ( i − j ) ! ⋅ m ! ( m − j ) ! = ( m − j i − j ) m j – ( m i ) i j _ = m ! i ! ( m − i ) ! ⋅ i ! ( i − j ) ! = m ! ( m − i ) ! ( i − j ) ! = ( m − j ) ! ( m − i ) ! ( i − j ) ! ⋅ m ! ( m − j ) ! = ( m − j i − j ) m j _
代入原式得:
ans = 1 ( m k ) L ∑ j = 0 { L j } k ∑ i = 0 ( n − m k − i ) ( m − j i − j ) m j – = 1 ( m k ) L ∑ j = 0 { L j } m j – k ∑ i = 0 ( n − m k − i ) ( m − j i − j ) = 1 ( m k ) L ∑ j = 0 { L j } m j – ( n − j k − j ) ans = 1 ( m k ) ∑ j = 0 L { L j } ∑ i = 0 k ( n − m k − i ) ( m − j i − j ) m j _ = 1 ( m k ) ∑ j = 0 L { L j } m j _ ∑ i = 0 k ( n − m k − i ) ( m − j i − j ) = 1 ( m k ) ∑ j = 0 L { L j } m j _ ( n − j k − j )
第三步运用了范德蒙德卷积 。
于是我们只需要求出第 L L 行的斯特林数值,就可以通过 O ( N ) O ( N ) 预处理阶乘及其逆元,对于每个询问 O ( L ) O ( L ) 得出答案。
这是个经典 trick,通过二项式反演以及 NTT 可以 O ( L log L ) O ( L log L ) 求出,可以看 P5395 第二类斯特林数·行 ,这里不多赘述。
总复杂度 O ( N + L ( log L + q ) ) O ( N + L ( log L + q ) ) 。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话