信息学竞赛CSP中组合数学知识进阶及经典题目

组合数学

组合数卷积(范德蒙德卷积)

∑ i = 0 k ( n i ) ( m k − i ) = ( n + m k ) \sum_{i=0}\limits^k\dbinom{n}{i}\dbinom{m}{k-i}=\dbinom{n+m}{k} i=0k(in)(kim)=(kn+m)

组合意义:有 n n n 个红球以及 m m m 蓝球,选出 i i i 个红球,再选出 k − i k-i ki 个蓝球,等价于 n n n 个红球和 m m m 个蓝球,任意选出 k k k 个球
∑ i = 0 k ( i n ) ( k − i m ) = ( k + 1 n + m + 1 ) \sum_{i=0}^k\limits\dbinom{i}{n}\dbinom{k-i}{m}=\dbinom{k+1}{n+m+1} i=0k(ni)(mki)=(n+m+1k+1)
组合意义:有 k + 1 k + 1 k+1 个球排成一排,先选择一个球涂成绿色,然后在绿球的左边的所有球中选出 n n n 个涂成红色,绿色右边的所有球中选出 m m m 个涂成蓝色,等价于 k + 1 k+1 k+1 个球排成一排,选出 n + m + 1 n+m+1 n+m+1 个球。

组合数前缀和

( 0 m ) + ( 1 m ) + ⋯ + ( n m ) = ( n + 1 m + 1 ) \dbinom{0}{m}+\dbinom{1}{m}+\dots+\dbinom{n}{m}=\dbinom{n+1}{m+1} (m0)+(m1)++(mn)=(m+1n+1)

组合意义:对于 n + 1 n+1 n+1 个球,选择其中一个涂红,再在红球的左边选择 m m m 个涂蓝,等价于 n + 1 n+1 n+1 个球中,选择 m + 1 m+1 m+1
f ( n , m ) = ( n 0 ) + ( n 1 ) + ⋯ + ( n m ) f(n,m)=\binom{n}{0}+\binom{n}{1}+\dots+\binom{n}{m} f(n,m)=(0n)+(1n)++(mn)
无法快速计算 f ( n , m ) f(n,m) f(n,m),但是可以 O ( n ) O(n) O(n) 算出 f ( 0 ∼ n , m ) f(0\sim n,m) f(0n,m)

计算方式:

f ( n , m ) = ∑ i = 0 m ( n i ) = ∑ i = 0 m ( ( n − 1 i ) + ( n − 1 i − 1 ) ) = ∑ i = 0 m ( n − 1 i ) + ∑ i = 0 m − 1 ( n − 1 i ) = 2 ∑ i = 0 m ( n − 1 i ) − ( n − 1 m ) = 2 f ( n − 1 , m ) − ( n − 1 m ) \begin{align*} &f(n,m)&=&\sum\limits_{i=0}^m\dbinom{n}{i}\\ &&=&\sum_{i=0}^m(\dbinom{n-1}{i}+\dbinom{n-1}{i-1}) \\ &&=&\sum_{i=0}^m\dbinom{n-1}{i}+\sum_{i=0}^{m-1}\dbinom{n-1}{i}\\ &&=&2\sum_{i=0}^m\dbinom{n-1}{i}-\dbinom{n-1}{m}\\ &&=&2f(n-1,m)-\dbinom{n-1}{m} \end{align*} f(n,m)=====i=0m(in)i=0m((in1)+(i1n1))i=0m(in1)+i=0m1(in1)2i=0m(in1)(mn1)2f(n1,m)(mn1)

其中 ② ② 式为组合恒等式: ( n m ) = ( n − 1 m ) + ( n − 1 m − 1 ) \dbinom{n}{m}=\dbinom{n-1}{m}+\dbinom{n-1}{m-1} (mn)=(mn1)+(m1n1)

其中 ③ ③ 式后项的 i i i 并非上式的 i i i,而是 i − 1 i-1 i1,所以上界的范围是到 m − 1 m-1 m1


C F 1327 E − C o u n t T h e B l o c k s \mathrm{CF1327E - Count\ The\ Blocks} CF1327ECount The Blocks

D e s c r i p t i o n \mathrm{Description} Description

给定正整数 n n n

对于一个数 t t t,定义一个块是 t t t 中的连续相等的一串数字。写下 0 ⋯ 1 0 n − 1 0\cdots10^n-1 010n1 的所有数,不足 n n n 位的用前导 0 0 0 补足 n n n 位。

对于每个 i = 1 ⋯ n i=1\cdots n i=1n,求这 1 0 n 10^n 10n 个数中一共有多少个长为 i i i 的块。

S o l u t i o n \mathrm{Solution} Solution

分类讨论:

  • i = n i=n i=n 时,答案为 10 10 10,即全部相同,只有 10 10 10 种选法
  • i < n i<n i<n
    • 当长度为 i i i 的连通块位于两边时: 10 × 9 × 1 0 n − i − 1 10\times 9\times 10^{n-i-1} 10×9×10ni1
    • 当长度为 i i i 的连通块位于中间时: 10 × 9 2 × 1 0 max ⁡ ( 0 , n − i − 2 ) 10\times9^2\times 10^{\max(0,n-i-2)} 10×92×10max(0,ni2)
A c c e p t e d C o d e \mathrm{Accepted\ Code} Accepted Code
#include <bits/stdc++.h>
#define int long longusing namespace std;typedef pair<int, int> PII;
typedef long long LL;const int MOD = 998244353;int ksm(int a, int b, int p)
{int Result = 1;while (b){if (b & 1) Result = Result * a % p;a = a * a % p;b >>= 1;}return Result;
}signed main()
{cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);int N;cin >> N;for (int i = 1; i <= N; i ++)if (i == N) cout << 10 << " ";else if (i == N - 1) cout << 10 * 9 * ksm(10, N - i - 1, MOD) * 2 % MOD << " ";else cout << (10 * 9 * ksm(10, N - i - 1, MOD) * 2 % MOD + (N - i - 1) * 10 * 9 * 9 % MOD * ksm(10, max(0ll, N - i - 2), MOD) % MOD) % MOD << " ";return 0;
}

C F 1761 D − C a r r y B i t \mathrm{CF1761D - Carry\ Bit} CF1761DCarry Bit

D e s c r i p t i o n \mathrm{Description} Description

定义 f ( a , b ) f(a,b) f(a,b) 表示二进制下计算 a + b a+b a+b 的进位次数。

给定 n , k n,k n,k,计算共有多少二元组 ( a , b ) ( 0 ≤ a , b ≤ 2 n ) (a,b)(0\le a,b\le 2^n) (a,b)(0a,b2n) 满足 f ( a , b ) = k f(a,b)=k f(a,b)=k

0 ≤ k < n ≤ 1 0 6 0\le k<n\le 10^6 0k<n106

S o l u t i o n \mathrm{Solution} Solution

首先,考虑一个暴力 DP:设 f i , j , 0 / 1 f_{i,j,0/1} fi,j,0/1 表示对于前 i i i 位,总共进位次数为 j j j,当前是否进位。

则有:
f i + 1 , j , 0 = 3 f i , j , 0 + f i , j , 1 f i + 1 , j + 1 , 1 = f i , j , 0 + 3 f i , j , 1 \begin{align*} f_{i+1,j,0}&=3f_{i,j,0}+f_{i,j,1}\\ f_{i+1,j+1,1}&=f_{i,j,0}+3f_{i,j,1} \end{align*} fi+1,j,0fi+1,j+1,1=3fi,j,0+fi,j,1=fi,j,0+3fi,j,1
那么,若当前用 x x x 表示是否进位,则有 3 3 3 的贡献保持不变, 1 1 1 的贡献发生翻转,转移路线如图:

请添加图片描述

如图所示,斜边表示翻转,横边表示保持原有状态,那么转移其实就是这上面的一条条路径。(第一行为不进位,第二行为进位)

若对于一条 01 01 01 路径,进位的次数是多少呢?其实是路径上 1 1 1 的个数。

那么,考虑枚举路径上 01 01 01 翻转的次数,记作 i i i。则路径上 1 1 1 的极大连通块的数量 ⌈ i 2 ⌉ \lceil \frac{i}{2}\rceil 2i,由于总共分成的连通块数量为 i + 1 i+1 i+1,所以 0 0 0 的极大连通块数量为 i + 1 − ⌈ i 2 ⌉ i+1-\lceil\frac{i}{2}\rceil i+12i。那么,由于需要 1 1 1 的个数为 K K K,那么加上初始状态 0 0 0(没有进位),总共 n + 1 n+1 n+1 个状态,这其中有 K K K 个为 1 1 1,那么就有 n + 1 − K n+1-K n+1K 个为 0 0 0

综上所述, 01 01 01 路径的数量应为将 K K K 1 1 1 划分成 ⌈ i 2 ⌉ \lceil \frac{i}{2}\rceil 2i 段的数量 n + 1 − K n+1-K n+1K 0 0 0 划分成 i + 1 − ⌈ i 2 ⌉ i+1-\lceil\frac{i}{2}\rceil i+12i 段的数量,通过隔板法可得: ( n − K i − ⌈ i 2 ⌉ ) ( K − 1 ⌈ i 2 ⌉ ) \dbinom{n-K}{i-\lceil\frac{i}{2}\rceil}\dbinom{K-1}{\lceil \frac{i}{2}\rceil} (i2inK)(2iK1)

不过,不要忘记对于保持不变,还有 3 3 3 的转移系数,所以还要乘 3 n − i 3^{n-i} 3ni

最终式子:
∑ i = 0 n 3 n − i ( n − K i − ⌈ i 2 ⌉ ) ( K − 1 ⌈ i 2 ⌉ ) \sum_{i=0}^n 3^{n-i}\dbinom{n-K}{i-\lceil\frac{i}{2}\rceil}\dbinom{K-1}{\lceil \frac{i}{2}\rceil} i=0n3ni(i2inK)(2iK1)

A c c e p t e d C o d e \mathrm{Accepted\ Code} Accepted Code
#include <bits/stdc++.h>
#define int long longusing namespace std;typedef pair<int, int> PII;
typedef long long LL;const int MAXN = 1e6 + 10, MOD = 1e9 + 7;int N, K;
int inv[MAXN], fact[MAXN], infact[MAXN], P3[MAXN];int C(int n, int m) { return m > n ? 0 : fact[n] * infact[m] % MOD * infact[n - m] % MOD; }signed main()
{cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);cin >> N >> K;inv[1] = 1;for (int i = 2; i <= N; i ++)inv[i] = (MOD - MOD / i) * inv[MOD % i] % MOD;fact[0] = infact[0] = P3[0] = 1;for (int i = 1; i <= N; i ++)fact[i] = fact[i - 1] * i % MOD, infact[i] = infact[i - 1] * inv[i] % MOD, P3[i] = P3[i - 1] * 3 % MOD;if (!K){cout << P3[N] << endl;return 0;}int res = 0;for (int i = 0; i <= N; i ++)res = (res + P3[N - i] * C(N - K, i + 1 - (i + 1) / 2 - 1) % MOD * C(K - 1, (i + 1) / 2 - 1) % MOD) % MOD;cout << res << endl;return 0;
}

[ A B C 134 F ] P e r m u t a t i o n O d d n e s s \mathrm{[ABC134F] Permutation\ Oddness} [ABC134F]Permutation Oddness

D e s c r i p t i o n \mathrm{Description} Description

定义一个 1 ∼ n 1 \sim n 1n 的排列 p p p 的「怪异度」为
∑ i = 1 n ∣ p i − i ∣ \sum_{i=1}^n|p_i-i| i=1npii
求「怪异度」为 k k k 1 ∼ n 1 \sim n 1n 的排列数,答案对 1 0 9 + 7 10^9+7 109+7 取模。


S o l u t i o n \mathrm{Solution} Solution

对于排列计数的问题,最为困难的地方在于如何去一一对应的计算排列数。

对于本题,将题目形式化为有 n n n 只老鼠,以及 n n n 个洞,老鼠去找洞(一个洞只能留一只老鼠),最终的「怪异度」为老鼠走过的距离,即每条边走过的次数之和。

那么,考虑对于位置 i i i,老鼠 i i i 可以去找 < i <i <i 的洞,也可以找 > i >i >i 的洞(洞也是类似的)。不过,如果一只老鼠找 > i >i >i 的洞,那么也必有一个 > i >i >i 的老鼠找 < i <i <i 的洞,即是选择是对称的。

所以,不妨设 f i , j , k f_{i,j,k} fi,j,k 表示前 i i i 只老鼠,有 j j j 只老鼠(也是 j j j 个洞,因为是对称的)是去找 > i >i >i 的位置的,目前的和为 k k k

f i , j , k f_{i,j,k} fi,j,k 转移到 i + 1 i+1 i+1 的时候,那么 i ↔ i + 1 i\leftrightarrow i+1 ii+1 这条边会被经过 2 j 2j 2j 次,因为 j j j ≤ i \le i i 老鼠取 > i >i >i 的位置, j j j 个洞会有 j j j > i >i >i 的老鼠所找到,所以会被经过 2 j 2j 2j 次。

那么,接下来分类讨论 j j j 的变化:

  • i + 1 i+1 i+1 号老鼠和洞都是向 > i + 1 >i+1 >i+1 的位置匹配的,那么 f i , j , k → f i + 1 , j + 1 , k + 2 j f_{i,j,k}\rightarrow f_{i+1,j+1,k+2j} fi,j,kfi+1,j+1,k+2j,因为会多一对。
  • i + 1 i+1 i+1 号老鼠和洞有一个向 > i + 1 >i+1 >i+1 的位置匹配,由于一个匹配好,另一个多出未匹配的一个,一消一加,刚好抵消掉,所以 j j j 不变,那么:
    • f i , j , k × j → f i + 1 , j , k + 2 j f_{i,j,k}\times j\rightarrow f_{i+1,j,k+2j} fi,j,k×jfi+1,j,k+2j,老鼠向 > i + 1 >i+1 >i+1 的位置匹配,洞会选择一个 ≤ i + 1 \le i+1 i+1 的老鼠,此时有 j j j 只老鼠是还未匹配的,所以任选一个,要乘 j j j
    • f i , j , k × j → f i + 1 , j , k + 2 j f_{i,j,k}\times j\rightarrow f_{i+1,j,k+2j} fi,j,k×jfi+1,j,k+2j,洞向 > i + 1 >i+1 >i+1 的位置匹配,后面分析完全一样
  • i + 1 i+1 i+1 号老鼠和洞都与 ≤ i + 1 \le i+1 i+1 的位置匹配,那么老鼠有 j j j 种选择,洞有 j j j 种选择,乘法原理总共是 j 2 j^2 j2 种,那么 f i , j , k × j 2 → f i + 1 , j − 1 , k + 2 j f_{i,j,k}\times j^2\rightarrow f_{i+1,j-1,k+2j} fi,j,k×j2fi+1,j1,k+2j
  • i + 1 i+1 i+1 号老鼠与 i + 1 i+1 i+1 号洞匹配,那么 j j j 不变: f i , j , k → f i + 1 , j , k + 2 j f_{i,j,k}\rightarrow f_{i+1,j,k+2j} fi,j,kfi+1,j,k+2j

综上所述,转移分如下 3 3 3 种:

  • f i , j , k → f i + 1 , j + 1 , k + 2 j f_{i,j,k}\rightarrow f_{i+1,j+1,k+2j} fi,j,kfi+1,j+1,k+2j
  • f i , j , k × ( 2 j + 1 ) → f i + 1 , j , k + 2 j f_{i,j,k}\times (2j+1)\rightarrow f_{i+1,j,k+2j} fi,j,k×(2j+1)fi+1,j,k+2j
  • f i , j , k × j 2 → f i + 1 , j − 1 , k + 2 j f_{i,j,k}\times j^2\rightarrow f_{i+1,j-1,k+2j} fi,j,k×j2fi+1,j1,k+2j

A c c e p t e d C o d e \mathrm{Accepted\ Code} Accepted Code
#include <bits/stdc++.h>
#define int long longusing namespace std;typedef pair<int, int> PII;
typedef long long LL;const int MAXN = 55, MOD = 1e9 + 7;int n, m;
int f[MAXN][MAXN][MAXN * MAXN];void add(int &a, int b) { a = (a + b) % MOD; }signed main()
{cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);cin >> n >> m;f[0][0][0] = 1;for (int i = 0; i <= n; i ++)for (int j = 0; j <= i; j ++)for (int k = 0; k <= m; k ++){add(f[i + 1][j + 1][k + 2 * j], f[i][j][k]); //洞与老鼠均与 > i 的老鼠与洞匹配add(f[i + 1][j][k + 2 * j], f[i][j][k] * (2 * j + 1) % MOD); //洞或老鼠中的一个与 > i 的位置匹配,令一个匹配内部;或该洞与该老鼠匹配if (j) add(f[i + 1][j - 1][k + 2 * j], f[i][j][k] * j * j); //均与 < i 且未匹配的点匹配}cout << f[n][0][m] << endl;return 0;
}

C F 1838 E − C o u n t S u p e r s e q u e n c e s \mathrm{CF1838E - Count\ Supersequences} CF1838ECount Supersequences

D e s c r i p t i o n \mathrm{Description} Description

给定一个长为 n n n 的序列 a a a ∀ i ∈ [ 1 , n ] , a i ∈ [ 1 , k ] \forall i\in[1,n],a_i\in[1,k] i[1,n],ai[1,k],有序列 b b b,满足 a a a b b b 的子序列, b i ∈ [ 1 , k ] b_i \in [1,k] bi[1,k] b b b 的长度为 m m m

求满足条件的 b b b 数组个数。


S o l u t i o n \mathrm{Solution} Solution

首先,考虑如何判断序列 A A A 是序列 B B B 的子序列,那么贪心的考虑必定是先找到 A 1 A_1 A1 B B B 中出现的最早的位置 p 1 p_1 p1 A 2 A_2 A2 B B B 序列出现的最早的位置 p 2 p_2 p2,使得 p 2 > p 1 p_2>p_1 p2>p1 … \dots A n A_n An B B B 序列出现最早的位置 p n p_n pn,使得 p n > p n − 1 p_n>p_{n-1} pn>pn1

那么,这个问题是给定子序列 A A A,求解有多少序列 B B B,使得 A A A B B B 的子序列。一个 N a i v e Naive Naive 的想法是在 A A A 序列每个位置前后插入数(类似隔板法),不过这样会算重。

那么,类似上面求子序列的过程,可以通过类似枚举 p p p 序列的方式来计数:
∑ p 1 < p 2 < ⋯ < p n ( k − 1 ) p n − n k m − p n \sum_{p_1<p_2<\dots<p_n} (k-1)^{p_n-n}k^{m-p_n} p1<p2<<pn(k1)pnnkmpn
一个最暴力的式子, k − 1 k-1 k1 是因为前 p n p_n pn 个数每个可以选择的位置(共 p n − n p_n-n pnn 个),都不能与后面接下来的 p p p 所对应的数重复,如果重复了,那么按照我们贪心的选择,必定会将 p p p 选择到该位置,所以只能填 k − 1 k-1 k1 个数,但是 p n p_n pn 后面的数就无所谓了!

继续狂推式子:
∑ p 1 < p 2 < ⋯ < p n ( k − 1 ) p n − n k m − p n = ∑ p n = n m ( p n − 1 n − 1 ) ( k − 1 ) p n − n k m − p n = ∑ p n = n m ( p n − 1 n − 1 ) ( k − 1 ) p n − n ∑ i = 0 m − p n ( m − p n i ) ( k − 1 ) m − p n − i = ∑ p n = n m ∑ i = 0 m − p n ( p n − 1 n − 1 ) ( m − p n i ) ( k − 1 ) m − p n − i + p n − n = ∑ p n = n m ∑ i = 0 m − p n ( p n − 1 n − 1 ) ( m − p n i ) ( k − 1 ) m − n − i = ( k − 1 ) m ∑ i = 0 m ( k − 1 ) − n − i ∑ p n = n m ( p n − 1 n − 1 ) ( m − p n i ) = ( k − 1 ) m ∑ i = 0 m ( k − 1 ) − n − i ( m n + i ) = ( k − 1 ) m ∑ i = n m ( k − 1 ) − i ( m i ) = ∑ i = n m ( k − 1 ) m − i ( m i ) \begin{align*} &\sum_{p_1<p_2<\dots<p_n} (k-1)^{p_n-n}k^{m-p_n}\\ =&\sum_{p_n=n}^m\binom{p_n-1}{n-1}(k-1)^{p_n-n}k^{m-p_n}\\ =&\sum_{p_n=n}^m\binom{p_n-1}{n-1}(k-1)^{p_n-n}\sum_{i=0}^{m-p_n}\binom{m-p_n}{i}(k-1)^{m-p_n-i}\\ =&\sum_{p_n=n}^m\sum_{i=0}^{m-p_n}\binom{p_n-1}{n-1}\binom{m-p_n}{i}(k-1)^{m-p_n-i+p_n-n}\\ =&\sum_{p_n=n}^m\sum_{i=0}^{m-p_n}\binom{p_n-1}{n-1}\binom{m-p_n}{i}(k-1)^{m-n-i}\\ =&(k-1)^m\sum_{i=0}^{m}(k-1)^{-n-i}\sum_{p_n=n}^m\binom{p_n-1}{n-1}\binom{m-p_n}{i}\\ =&(k-1)^m\sum_{i=0}^{m}(k-1)^{-n-i}\binom{m}{n+i}\\ =&(k-1)^m\sum_{i=n}^{m}(k-1)^{-i}\binom{m}{i}\\ =&\sum_{i=n}^{m}(k-1)^{m-i}\binom{m}{i}\\ \end{align*} ========p1<p2<<pn(k1)pnnkmpnpn=nm(n1pn1)(k1)pnnkmpnpn=nm(n1pn1)(k1)pnni=0mpn(impn)(k1)mpnipn=nmi=0mpn(n1pn1)(impn)(k1)mpni+pnnpn=nmi=0mpn(n1pn1)(impn)(k1)mni(k1)mi=0m(k1)nipn=nm(n1pn1)(impn)(k1)mi=0m(k1)ni(n+im)(k1)mi=nm(k1)i(im)i=nm(k1)mi(im)
好,在一番辛苦的推倒下也是成功的推到了一个简单的式子,不过还是得 O ( m ) O(m) O(m) 做,还是过不去。我们先来讲解一下式子的含义吧:

  • 第一步,由于后面只跟 p n p_n pn 有关,所以只用枚举 p n p_n pn,剩余的 p 1 ∼ n − 1 p_{1\sim n-1} p1n1,可以用组合数算,即在 p n − 1 p_n-1 pn1 个位置里选 n − 1 n-1 n1 个数
  • 第二步,通过 二项式定理 将 k m − p n k^{m-p_n} kmpn 化为 ( ( k − 1 ) + 1 ) m − p n ((k-1)+1)^{m-p_n} ((k1)+1)mpn
  • 第三步,将第二个 ∑ \sum 提到前面,并将两个 ( k − 1 ) (k-1) (k1) 的指数次幂合并
  • 第四步,化简 ( k − 1 ) (k-1) (k1) 的指数次幂
  • 第五步,将 ( k − 1 ) m − n − i (k-1)^{m-n-i} (k1)mni 替换为 ( k − 1 ) m ( k − 1 ) − n − i (k-1)^m(k-1)^{-n-i} (k1)m(k1)ni,并将 ( k − 1 ) m (k-1)^m (k1)m 提前, ( k − 1 ) − n − i (k-1)^{-n-i} (k1)ni 放置在第一个 ∑ \sum 的后面
  • 第六步,观察发现后面的两个组合数相乘,其实可以用上文的组合数卷积,因为上指标的和总是一个定值。
  • 第七步,将 i i i 替换为 i + n i+n i+n
  • 第八步,将 ( k − 1 ) m (k-1)^m (k1)m 再合并回 ( k − 1 ) − i (k-1)^{-i} (k1)i 得到 ( k − 1 ) m − i (k-1)^{m-i} (k1)mi

那么,如何继续优化呢?观察可知,如果 ∑ \sum i i i 0 0 0 开始枚举,其实就是二项式定理,那么不妨令其从 0 0 0 开始,后面在减去即可:
∑ i = n m ( k − 1 ) m − i ( m i ) = ∑ i = 0 m ( k − 1 ) m − i ( m i ) − ∑ i = 0 n − 1 ( k − 1 ) m − i ( m i ) = k m − ∑ i = 0 n − 1 ( k − 1 ) m − i ( m i ) \begin{align*} &\sum_{i=n}^{m}(k-1)^{m-i}\binom{m}{i}\\ =&\sum_{i=0}^m(k-1)^{m-i}\binom{m}{i}-\sum_{i=0}^{n-1}(k-1)^{m-i}\binom{m}{i}\\ =&k^m-\sum_{i=0}^{n-1}(k-1)^{m-i}\binom{m}{i} \end{align*} ==i=nm(k1)mi(im)i=0m(k1)mi(im)i=0n1(k1)mi(im)kmi=0n1(k1)mi(im)
这样,我们就可以在 O ( n log ⁡ m ) O(n\log m) O(nlogm) 的时间复杂度内解决该问题了!

A c c e p t e d C o d e \mathrm{Accepted\ Code} Accepted Code
#include <bits/stdc++.h>
#define int long longusing namespace std;typedef pair<int, int> PII;
typedef long long LL;const int MOD = 1e9 + 7;int ksm(int a, int b, int p)
{int Result = 1;while (b){if (b & 1) Result = Result * a % p;a = a * a % p;b >>= 1;}return Result;
}void solve()
{int n, m, k, a;cin >> n >> m >> k;for (int i = 1; i <= n; i ++)cin >> a;int res = (ksm(k, m, MOD) - ksm(k - 1, m, MOD) + MOD) % MOD, up = 1, dw = 1;for (int i = 1; i < n; i ++){up = up * (m - i + 1) % MOD, dw = dw * ksm(i, MOD - 2, MOD) % MOD;res = (res - (up * dw % MOD * ksm(k - 1, m - i, MOD) % MOD) + MOD) % MOD;}cout << res << endl;
}signed main()
{cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);int Data;cin >> Data;while (Data --)solve();return 0;
}

组合谔谔天地灭,代数推导保平安!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2815108.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

线上故障的排查清单

线上故障主要会包括CPU、磁盘、内存以及网络问题&#xff0c;而大多数故障可能会包含不止一个层面的问题&#xff0c;所以进行排查时候尽量四个方面依次排查一遍。 同时例如 jstack、jmap 等工具也是不囿于一个方面的问题的&#xff0c;基本上出问题就是df、free、top 三连&am…

全网最详细Python自动化测试(从零搭建完整python自动化测试框架)

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号&#xff1a;互联网杂货铺&#xff0c;回复1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 自动化测试介绍 自动化测试(Automated Testing)&#x…

基于java Springboot实现课程评分系统设计和实现

基于java Springboot实现课程评分系统设计和实现 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末获取源…

SpringMVC 学习(五)之域对象

目录 1 域对象介绍 2 向 request 域对象共享数据 2.1 通过 ServletAPI (HttpServletRequest) 向 request 域对象共享数据 2.2 通过 ModelAndView 向 request 域对象共享数据 2.3 通过 Model 向 request 域对象共享数据 2.4 通过 map 向 request 域对象共享数据 2.5 通过…

Ant for Blazor做单个表的增删查改

Ant for Blazor做单个表的增删查改 2024年02月27日花了一天时间弄出来了&#xff0c;基本弄好了&#xff0c;vs2022blazor servernet8,引用的AntDesign版本是0.17.4 代码里的model和repository是用自己牛腩代码生成器生成的东西&#xff0c;sqlsugar的&#xff0c;记得在prog…

分布式一致性算法-Paxos翻译和注解

Paxos是解决不可靠处理器&#xff08;不可靠是指处理器可能故障&#xff09;网络中一致性问题(consensus)的一个协议族。一致性&#xff08;或者共识&#xff09;是在一组参与者之间对一个结果达成共识的过程。当参与者或者它们的交互媒介可能发生故障的时候&#xff0c;这个问…

幻兽帕鲁(Palworld 1.4.11.5.0)私有服务器搭建(docker版)

文章目录 说明客户端安装服务器部署1Panel安装和配置docker服务初始化设置设置开机自启动设置镜像加速 游戏服务端部署游戏服务端参数可视化配置 Palworld连接服务器问题总结 服务端升级&#xff08;1.5.0&#xff09; 说明 服务器硬件要求&#xff1a;Linux系统/Window系统&a…

JS总览-JS高级程序设计4-学习笔记

JS简史 1995年 JS 问世&#xff0c;彼时其主要任务是替代服务器端语言处理输入验证 1995年网景公司的 Brendan Eich 开发了一个脚注Live Script的脚步语言&#xff0c;后来网景公司与 Sun 公司结盟&#xff0c;更名 Live Script 为 Java Script 由于微软发布 IE3 时包含了自己…

iMazing 3.0.0.3 for mac 中文破解版2024最新图文安装教程

我们刚刚发布了iMazing 3.0.0.3 for mac 中文版本。Windows和macOS用户现在都可以试驾并体验iPhone管理的未来。 备受期待的第一个Windows版本得益于过去几个月macOS测试版的所有改进&#xff0c;使其成为一个稳定的初始版本。 我们的开发团队创造了一种无缝的外观和体验&#…

关于uniapp小程序的分包问题

开发uniapp小程序时&#xff0c;在打包上传代码时会出现超出2M的打包限制不能上传&#xff0c;那么我们该怎么做呢&#xff1f; 1.对于图片&#xff0c;将图片从后端服务取&#xff0c;尽量不要放在静态资源&#xff0c;图片体积会影响打包大小。 2.使用分包&#xff0c;tabb…

LNMP 架构

PHP(Hypertext Preprocessor 超文本预处理器)是通用服务器端脚本编程语言&#xff0c;主要用于web开发实现动态web页面&#xff0c;也是最早实现将脚本嵌入HTML源码文档中的服务器端脚本语言之一。同时&#xff0c;php还提供了一个命令行接口&#xff0c;因此&#xff0c;其也可…

哪个牌子的电视盒子好用?2024超强电视盒子排名

最近很多朋友问我电视盒子的相关问题&#xff0c;就目前来说&#xff0c;电视盒子的地位依然是不可取代的。我近来要发布的测评内容是哪个牌子的电视盒子好用&#xff0c;耗时两周进行对比后整理了电视盒子排名&#xff0c;看看哪些电视盒子是最值得入手的吧。 NO.1——泰捷新品…

安装极狐GitLab Runner并测试使用

本文继【新版极狐安装配置详细版】之后继续 1. 添加官方极狐GitLab 仓库&#xff1a; 对于 RHEL/CentOS/Fedora&#xff1a; curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh" | sudo bash2. 安装最新版本的极狐G…

ChatGPT提示词工程师AI大神吴恩达2023年视频课程学习实践

前言 刚才看了一个视频系列教程&#xff0c;很短&#xff0c;但收获很大&#xff0c;毕竟是一手知识来源&#xff0c;吴恩达大神亲自讲解&#xff0c;他说的话&#xff0c;我都信。这里写个笔记&#xff0c;顺便把知识点实践一下。视频可以去B站上搜索 吴恩达 prompt &#xf…

log4j 基础使用入门教程

一、Log4j介绍 在项目中&#xff0c;不管是开发人员写代码还是测试人员写的测试代码一般都需要做一些日志来记录项目的行为&#xff0c;以便更好的跟踪项目中的一些交互和问题。 Log4j ( Logger For Java ) , Java 日志的记录包。 官方网站 。Log4j 是 Apache 的一个开源项目…

C++之标准库中string的底层实现方式

目录 1、Eager Copy(深拷贝) 2、COW(Copy-On-Write)写时复制 2.1写时复制的实现 3、SSO&#xff08;Short String Optimization)短字符串优化 4、最佳策略 5、线程安全性 我们都知道&#xff0c; std::string的一些基本功能和用法了&#xff0c;但它底层到底是如何实现的…

李沐动手学习深度学习——3.4练习

理解极大似然估计 很巧妙的解释了为什么使用均方误差&#xff0c;因为均方误差是一种似然估计的变种&#xff0c;而对于逻辑回归softmax而言&#xff0c;更好的解释了其中存在exp 1. 我们可以更深入地探讨指数族与softmax之间的联系。 1. 计算softmax交叉熵损失l(y, ˆy)的二阶…

【C++历练之路】map与set的必备使用指南

W...Y的主页 &#x1f60a; 代码仓库的分享&#x1f495; &#x1f354;序言&#xff1a; C作为一门历史悠久且功能强大的编程语言&#xff0c;其标准模板库&#xff08;STL&#xff09;为开发者提供了一套丰富的数据结构和算法&#xff0c;极大地促进了软件开发的效率和质量…

Python打发无聊时光:10.用flask创造按键控制的网页小游戏

游戏介绍: 《秦蓝大冒险》是一款简单而紧张的追逐游戏。在这个游戏中&#xff0c;玩家将控制一名名叫“吕千”的角色&#xff0c;试图在一个封闭的空间内逃避一个名为“秦蓝”的追逐者。随着时间的推移&#xff0c;“秦蓝”会不断追踪玩家的位置&#xff0c;努力捕捉到他。 游…

干货!Python字符串填充、去除、分割与合并

1.center() 将字符串按照指定内容填充到指定长度&#xff0c;默认填充的内容是空格 str1 "今天天气好晴朗"print(str1.center(50)) # 使用空间将原字符串填充到50个长度&#xff0c;原内容居中print(str1.center(50, "*")) # 使用 * 将原字符串填…