洛谷 P4859 已经没有什么好害怕的了 题解(DP,二项式反演)

组合数学与容斥

组合数

几个比较出名的公式:

\[\binom{n}{m} = \frac{n!}{m!(n-m)!} \]

\(\sum_{i=1}^m a_i = n, a_i \geq 1: \binom{n-1}{m-1}\)
线性递推常用: \(\binom{n}{m} = \binom{n-1}{m} + \binom{n-1}{m-1}\)
上指标前缀和: \(\sum_{i=0}^n \binom{i}{m} = \binom{n+1}{m+1}\)
范德蒙德卷积: \(\sum_{i=0}^n \binom{n}{i}\binom{m}{k-i} = \binom{n+m}{k}\)
Lucas 定理: \(\binom{n}{m} \equiv \binom{n \bmod p}{m \bmod p}\binom{\lfloor n/p \rfloor}{\lfloor m/p \rfloor} \pmod p\)

洛谷 P7481 梦现时刻

给定 \(n,m\) ,保证 \(m\le n\),令 \(F(a,b)=\sum_{i=0}^{b}\binom{b}{i}\binom{n-i}{a}\)

\(\bigoplus_{a=1}^{m}\bigoplus_{b=1}^{m}(F(a,b) \bmod 998244353)\)

其中 \(\oplus\) 表示异或运算。

\(m\le 5000,n\le 10^9\)

稍微分析一下,我们希望把这个 \(F(a,b)\) 用若干个 \(F(a\pm 1, b\pm 1)\) 表示出来,这样就能递推了。

先把 \(F(a,b)\) 拆成 \(F(a,b)=[{b-1\choose i}+{b-1\choose i-1}]{n-i\choose a}\),这样我们发现括号里的第一项与右边这一项乘起来恰好就是 \(F(a,b-1)\)。但是我们还剩下一个 \({b-1\choose i-1}\) 没有处理。由于它有一个 \(i-1\),所以我们想要右边也出现一个 \(i-1\),于是将右边拆成 \({n-i+1\choose a+1}-{n-i\choose a+1}\)

于是你发现,有 \(F(a,b)=\sum_i [{b - 1 \choose i}+{b-1\choose i-1}][{n-i+1 \choose a+1}-{n-i \choose a+1}]\)。不妨从左到右标成 \(A,B,C,D\),我们要求的 \(F(a,b)\) 就等于 \((A+B)(C-D)\),再分析一下发现有 \(F(a,b-1)=AC-AD,F(a+1,b-1)=AD=BC,F(a+1,b)=AD+BD\),于是凑一下系数就得到:

\[\boxed{F(a,b)=F(a,b-1)-F(a+1,b)+2F(a+1,b-1)} \]

于是就可以递推了。时间复杂度 \(O(m^2)\)

const int MAXN = 5e3 + 5, mod = 998244353;
int n, m, f[MAXN][MAXN], C[MAXN][MAXN], T[MAXN]; // T[i] = (n-i \choose m)

int quickpow(int a, int b) {
	int ret = 1;
	while (b) {
		if (b & 1) ret = ret * a % mod;
		a = a * a % mod; b >>= 1;
	}
	return ret;
}

void work() {
	cin >> n >> m;
	f[1][0] = n;
	for (int a = 2; a <= m; ++a) {
		f[a][0] = f[a - 1][0] * (n - a + 1) % mod * quickpow(a, mod - 2) % mod;
	}
	for (int i = 0; i <= m; ++i) 
		C[i][0] = 1;
	for (int i = 1; i <= m; ++i) {
		for (int j = 1; j <= m; ++j) {
			C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod;
		}
	}
	int facm = 1; T[0] = 1;
	for (int i = 1; i <= m; ++i) {
		facm = facm * i % mod;
		T[0] = T[0] * (n - m + i) % mod;
	}
	T[0] = T[0] * quickpow(facm, mod - 2) % mod;
	for (int i = 1; i <= m; ++i) {
		T[i] = T[i - 1] * (n - i + 1 - m) % mod * quickpow(n - i + 1, mod - 2) % mod;
	}
	for (int b = 1; b <= m; ++b) {
		for (int i = 0; i <= b; ++i) {
			f[m][b] = (f[m][b] + C[b][i] * T[i] % mod) % mod;
		}
	}
	for (int b = 1; b <= m; ++b) {
		for (int a = m - 1; a; --a) {
			f[a][b] = (f[a][b - 1] - f[a + 1][b] + 2 * f[a + 1][b - 1]) % mod;
			f[a][b] = (f[a][b] + mod) % mod;
		}
	}
	int ans = 0;
	for (int a = 1; a <= m; ++a) {
		for (int b = 1; b <= m; ++b) {
			ans ^= f[a][b];
		}
	}
	cout << ans << endl;
}

/*
g++ -o LG7481 LG7481.cpp -O2 -std=c++14 -Wall -DLOCAL_TEST && LG7481.exe < test.in
*/

组合数

求 $ \sum_{a_1=l_1}^{r_1} \dots \sum_{a_n=l_n}^{r_n} \binom{m}{a_1+a_2+\dots+a_n} \pmod p$

\(n \le 18, 1 \le m \le 10^{18}, 1 \le l_i \le r_i \le 10^{16}, p \in \{2, 3, 5, 7\}\)

这个题是正睿私题没地方交,所以口胡一下。

首先我们遇到这种取值范围是一个区间的题可以容斥一下,但是这个题容斥比较厉害的地方在于他是将答案容斥为 \([a_i \ge l_i] - [a_i>r_i]\),这么做是为了方便后面数位 DP 计数。然后现在问题转换为每一个 \(a_i\) 有一个 \(a_i\ge b_i\) 的限制。

接下来,我们枚举 \(c=\sum a_i\),对于一个固定的 \(c\),我们发现其实他的贡献是确定的,也就是 \({m\choose c}{c-sum+n-1\choose n-1}\),其中 \(sum=\sum b_i\)。第一项是题目给的系数,第二项是把这多出来的 \(c-sum\) 个分配到这些 \(a_i\) 的方案数。

然后现在也就是要算这个东西对所有 \(c\) 的贡献,直接用 Lucas 定理+数位 DP \(c\)\(p\) 进制下的每一位即可。

时间复杂度 \(O(2^n p\log_{p} m)\)。由于是口胡没有代码。

LOJ6300 博弈论与概率统计

Alice 和 Bob 在玩一个双人游戏。每一轮中,Alice 有 \(p\) 的概率胜利,\(1 - p\) 的概率失败,不会出现平局。

双方初始时各有 \(0\) 分,当一个人胜利的时候,他会获得一分,失败则扣掉一分。遗憾的是,博弈论世界的人目前是无法理解负数的,因此,如果某个人输掉一轮比赛的时候他只有 \(0\) 分,那么他就不会被扣分(对方会照常加一分)。游戏一共要进行 \(N + M\) 轮,Alice 想请你帮她算算在游戏结束时她的得分的数学期望。

“这算啥,我小 \(L\) 分分钟搞定!”。比小 \(L\) 更熟练的你当然也是随手就算出来了,但就在你打算告诉 Alice 答案之前,博弈论世界之神——temporaryDO 出现了,他给大家带来了一个重要信息:这 \(N + M\) 轮游戏中,Alice 恰好赢了 \(N\) 轮!

熟知条件概率那套理论的你立刻注意到,你需要修改自己的计算方法来得到正确的答案了。

为了避免精度问题,请将结果对 \(10^9 + 7\) 取模。即,我们的数据保证答案是一个有理数 \(\frac{p}{q}\),且有 \(10^9 + 7 \nmid q\),你只需要找到一个整数 \(x \in [0, 10^9 + 7)\) 使得 \(qx \equiv p \pmod{10^9 + 7}\) 即可。

这个题的转化非常神。

首先发现给的这个 \(p\) 是没有用的,因为赢了输了多少局都是确定的。

然后,如果我们把初始状态看成一个坐标系上的 \((0,0)\),终点看成 \((n,m)\),相当于是我们每次赢就往右走一步,输就往上走一步。每次赢了就 \(x\gets x+1\),输了就 \(x\gets \max(x-1,0)\)。我们现在要求 \(E(x)\)

发现得分不好确定的原因是,我们要对 \(0\)\(\max\)。如果没有这个对 \(0\)\(\max\) 的操作,我们的得分就是 \(n-m\)

考虑这个对 \(0\)\(\max\) 的操作,在我们的坐标系上是长成什么样的。考虑第一次得分为 \(0\) 且下一局输了的情况,这时由于得分为 \(0\),我们一定在 \(y=x\) 这条线上,然后再往上走一步,但是得分不会 \(-1\),于是,相当于是第一次碰到 \(y=x+1\) 这条线的时候,我们就给得分 \(+1\)。同理,第二次得分为 \(0\) 且下一局输了的情况可以看成是在 \(y=x+1\) 这条线上再向上走一步,也就是第一次碰到 \(y=x+2\)

由于我们有 $E(x)=P(x\ge 1)+P(x\ge 2)+\cdots $,于是相当于是要求有多少条路径满足碰到了 \(y=x+1,y=x+2,\cdots\) 这些直线。

怎么求呢?根据反射原理(就是用来推卡特兰数的那个),如果我们想求经过了 \(y=x+k\) 上方到达 \((n,m)\) 的路径数,我们可以把它按照第一次碰到 \(y=x+k\) 的点分成前后两部分,第一部分路径不变,第二部分路径对 \(y=x+k\) 这条路径做轴对称反射,这样原先在 \((n,m)\) 的终点就变成了 \((m-k,n+k)\)。于是我们发现,任意一条最终终点在 \((m-k,n+k)\) 的路径,在通过 \(y=x+k\) 反射回去后,就一一对应了一条原先的合法路径。所以,经过 \(y=x+k\) 的路径数,就是 \(\binom{m+n}{n+k}\)

\(n\ge m\) 的时候,总的贡献数相当于是 \((n-m)\times \binom{n+m}{n} + \sum\limits_{k=1}^m \binom{m+n}{n+k}\),后面这项化简一下得到 \(\sum\limits_{k=0}^{m-1}\binom{m+n}{k}\)。当 \(n<m\) 的时候同理,此时 \(k\) 需要 \(\ge m-n\)(不然得分就会为负数,显然不合法),此时答案为 \(\sum\limits_{k=0}^{n-1}\binom{n+m}{k}\)。由于我们要求的是期望,所以上面这两种情况都要除以一个 \(\binom{n+m}{n}\) 的总方案数。

于是现在问题就变成了,给定 \(x,y\),如何快速求 \(\sum\limits_{k=0}^x \binom{y}{k}\)。这个问题可以用莫队解决。当 \(x\) 变成 \(x\pm 1\) 的时候,相当于是增加或减少了一项 \(\binom{y}{x/x+1}\),直接统计即可。当 \(y\) 变成 \(y+1\) 的时候,相当于多出了 \(\sum\limits_{k=0}^x \binom{y+1}{k}-\binom{y}{k}=\sum\limits_{k=0}^x \binom{y}{k-1}\),观察到这个东西相当于是原先我们的 \(ans\) 少了 \(\binom{y}{x}\) 这一项,所以答案就会增加 \(ans-\binom{y}{x}\),也就是 \(ans=2ans-\binom{y}{x}\)。减少同理,最后 \(ans=\frac{ans+\binom{y-1}{x}}2\)

最终时间复杂度 \(O(n\sqrt n)\)

const int MAXN = 5e5 + 5, mod = 1e9 + 7, N = 5e5;
int q, _, bel[MAXN], L[MAXN], R[MAXN], ans[MAXN], now, inv2;
int fac[MAXN], ifac[MAXN];

struct _query {
	int x, y, n, m, id;
	bool operator < (const _query b) const {
		if (bel[x] == bel[b.x]) {
			if (bel[x] & 1) return y < b.y;
			else return y > b.y;
		}
		return bel[x] < bel[b.x];
	}
} qr[MAXN];

int quickpow(int a, int b) {
	int ret = 1;
	while (b) {
		if (b & 1) ret = 1ll * ret * a % mod;
		a = 1ll * a * a % mod; b >>= 1;
	}
	return ret;
}

int C(int n, int m) { // n choose m
	if (n < m) return 0;
	return 1ll * fac[n] * ifac[n - m] % mod * ifac[m] % mod;
}

int Cinv(int n, int m) { // 1 / (n choose m)
	if (n < m) return 0;
	return 1ll * ifac[n] * fac[n - m] % mod * fac[m] % mod;
}

void addx(int x, int y) {
	now = (now + C(y, x)) % mod;
}

void delx(int x, int y) {
	now = ((now - C(y, x)) % mod + mod) % mod;
}

void addy(int x, int y) {
	now = ((2ll * now % mod - C(y - 1, x)) % mod + mod) % mod;
}

void dely(int x, int y) {
	now = 1ll * (now + C(y - 1, x)) % mod * inv2 % mod;
}

void work() {
	cin >> q >> _;
	int B = sqrt(N), cnt = 0;
	for (int i = 1; i <= N; i += B) {
		cnt++;
		L[cnt] = i;
		R[cnt] = min(i + B - 1, N);
		for (int j = L[cnt]; j <= R[cnt]; ++j) {
			bel[j] = cnt;
		}
	}
	fac[0] = 1;
	for (int i = 1; i <= N; ++i)
		fac[i] = 1ll * fac[i - 1] * i % mod;
	ifac[N] = quickpow(fac[N], mod - 2);
	for (int i = N - 1; i >= 0; --i)
		ifac[i] = 1ll * ifac[i + 1] * (i + 1) % mod;
	inv2 = quickpow(2, mod - 2);

	for (int i = 1; i <= q; ++i) {
		int n, m; cin >> n >> m;
		if (n < m) {
			qr[i] = {n - 1, n + m, n, m, i};
		} else {
			qr[i] = {m - 1, n + m, n, m, i};
		}
	}
	sort(qr + 1, qr + 1 + q);

	int l = 0, r = 1; now = 1;
	for (int i = 1; i <= q; ++i) {
		while (r < qr[i].y) {
			++r; addy(l, r);
		}
		while (l > qr[i].x) {
			delx(l, r); l--;
		}
		while (r > qr[i].y) {
			dely(l, r); r--;
		}
		while (l < qr[i].x) {
			l++; addx(l, r);
		}
		ans[qr[i].id] = 1ll * now * Cinv(qr[i].n + qr[i].m, qr[i].n) % mod;
		if (qr[i].n > qr[i].m) ans[qr[i].id] = (ans[qr[i].id] + (qr[i].n - qr[i].m)) % mod;
	} 
	for (int i = 1; i <= q; ++i)
		cout << ans[i] << endl;
}

二项式反演

形式一:如果 \(f_n=\sum\limits_{i=0}^n \binom{n}{i} g_i\),那么 \(g_n=\sum\limits_{i=0}^n (-1)^{n-i} \binom{n}{i}f_i\)。这种形式说明了“至多(也就是 \(f_n\))”与“恰好(也就是 \(g_n\))”之间的互推关系。

形式二:如果 \(f_k=\sum\limits_{i=k}^n \binom{i}{k} g_i\),那么 \(g_k=\sum\limits_{i=k}^n(-1)^{i-k}\binom{i}{k}f_i\)。这种形式说明了“至少(也就是 \(f_k\))”与“恰好(也就是 \(g_k\))”之间的互推关系。

二项式反演推导过程

以第一种形式为例为例。把 \(f_i\) 的定义带到 \(g_n\) 的式子里,得到:

\[g_n=\sum\limits_{i=0}^n (-1)^{n-i}\binom{n}{i}\sum\limits_{j=0}^i \binom{i}{j}g_j \]

我们现在想证明,后面这一堆其实就是 \(g_n\)。于是我们其实可以对于每一个 \(j\),计算 \(g_j\) 到底贡献了多少次:

\[g_n=\sum\limits_{i=0}^n\sum\limits_{j=0}^i (-1)^{n-i}\binom{n}{i}\binom{i}{j}g_j \]

然后我们发现,其实 \(\binom{n}{i}\binom{i}{j}\) 这一项就是先从 \(n\) 个里选 \(i\) 个标为 A,再从中选 \(j\) 个标为 AB。我们可以换一个顺序,先从 \(n\) 个中选 \(j\) 个标为 AB,再从剩下的 \(n-j\) 个选出 \(i-j\) 个标为 A。所以 \(\binom{n}{i}\binom{i}{j}=\binom{n}{j}\binom{n-j}{i-j}\)。于是:

\[g_n=\sum\limits_{i=0}^n\sum\limits_{j=0}^i (-1)^{n-i}\binom{n}{j}\binom{n-j}{i-j}g_j\\ =\sum\limits_{j=0}^n\binom{n}{j}g_j\sum\limits_{i=j}^n (-1)^{n-i}\binom{n-j}{i-j} \]

注意我们第二步交换了 \(i,j\) 的求和顺序。令 \(i=n-i\),则式子为:

\[g_n=\sum\limits_{j=0}^n\binom{n}{j}g_j\sum\limits_{i=0}^{n-j} (-1)^{i}\binom{n-j}{i} \]

注意到 \(\sum\limits_{i=0}^{n-j}(-1)^{i}\binom{n-j}{i}\),其实就是 \((1+(-1))^{n-j}\) 展开之后的形式。对于所有 \(j\ne n\),这个式子最后就是 \(0\)。当 \(j=n\) 时,式子为 \(1\)。于是,只有 \(j=n\) 的时候有一次贡献,也就是 \(g_n=g_n\)。证毕。

对于第二种形式,证明是类似的,这里不再重复展开。

洛谷 P4859 已经没有什么好害怕的了

给两个长为 \(n\) 的数组 \(a, b,\) 求将 \(a_i, b_j\) 两两匹配使得 \(a_i > b_j\) 的数量比 \(a_i < b_j\) 的数量多 \(k\)。数字不重复, \(k \le n \le 2000\)

注意到,其实 \(a_i>b_j\)\(a_i<b_j\) 分别的个数都是确定的,其中需要有 \(\frac{n+k}{2}\)\(a_i>b_j\)\(\frac{n-k}{2}\)\(a_i<b_j\)。于是问题就被转化成,有多少种将 \(a_i,b_j\) 两两配对的方案,使得 \(a_i>b_j\) 的个数恰好为 \(\frac{n+k}{2}\)。如果 \(n+k\) 是奇数那么无解。下文为了表述方便,令 \(k=\frac{n+k}{2}\)

然后我们发现出现了“恰好”的限制,“恰好”的限制一般来讲是不好计数的。遇到这种问题,我们可以先求出“至少”的方案数,然后再通过二项式反演推出恰好的方案数。

首先我们将 \(a_i,b_i\) 都从小到大排序,这样对于每一个 \(a_i\) 来说,他能匹配的 \(b_j\) 恰好就是一段前缀,且这个前缀的长度只增不减。接下来,考虑设 \(f_{i,j}\) 表示考虑了 \(a\) 的前 \(i\) 个数,其中我们钦定匹配了 \(j\) 对(这里的钦定就是恰好的意思,剩下的 \(a_i\) 是否匹配我们不管)的匹配方案数。注意这里状态不是所有的数的匹配方案数,而是指的是我们钦定的那些数的匹配方案数。因为如果我们把状态设为了前者,转移就不太方便了。

然后现在我们考虑怎么做转移。如果 \(a_i\) 我们要钦定他和一个 \(b\) 去匹配,那么一共有 \(cnt_i-j\) 种方案,其中 \(cnt_i\) 是比 \(a_i\) 小的 \(b\) 的数量。如果 \(a_i\) 不与任意一个 \(b\) 去匹配,那么方案数就不变。于是有:

\[f_{i,j}\gets f_{i-1,j-1}\times (cnt_i - (j-1)) + f_{i-1,j} \]

当我们算完之后,再统一算剩下的没有钦定的数的贡献:

\[f_{n,k}\gets f_{n,k}\times (n-k)! \]

现在我们有了【至少选 \(k\)\(a_i>b_j\) 的方案数 \(f_{n,k}\)】,我们想要推回恰好选 \(k\) 个的方案数 \(ans_k\),因为有:

\[f_{n,k}=\sum_{i=k}^n\binom{i}{k}ans_i \]

利用二项式反演,我们就能求出 \(ans_i\) 了:

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

const int MAXN = 2e3 + 5, mod = 1e9 + 9;
int n, k, f[MAXN][MAXN], cnt[MAXN], a[MAXN], b[MAXN], fac[MAXN], ifac[MAXN];

void add(int &x, int y) {
	x += y;
	if (x >= mod) x -= mod;
}

int quickpow(int a, int b) {
	int ret = 1;
	while (b) {
		if (b & 1) ret = ret * a % mod;
		a = a * a % mod; b >>= 1;
	}
	return ret;
}

int C(int n, int m) {
	if (n < m) return 0;
	return fac[n] * ifac[n - m] % mod * ifac[m] % mod;
}

void work() {
	cin >> n >> k;
	for (int i = 1; i <= n; ++i)
		cin >> a[i];
	for (int i = 1; i <= n; ++i)
		cin >> b[i];
	sort(a + 1, a + 1 + n);
	sort(b + 1, b + 1 + n);
	if ((n + k) % 2 == 1) return cout << 0 << endl, void();
	k = (n + k) / 2;
	int j = 0;
	for (int i = 1; i <= n; ++i) {
		while (j < n && b[j + 1] < a[i]) ++j;
		cnt[i] = j;
	}
	f[0][0] = 1;
	for (int i = 1; i <= n; ++i) {
		for (int j = 0; j <= n; ++j) {
			f[i][j] = f[i - 1][j];
			if (j > 0 && j <= cnt[i]) add(f[i][j], f[i - 1][j - 1] * (cnt[i] - (j - 1)) % mod);
		}
	}
	fac[0] = 1;
	for (int i = 1; i <= n; ++i)
		fac[i] = fac[i - 1] * i % mod;
	ifac[n] = quickpow(fac[n], mod - 2);
	for (int i = n - 1; i >= 0; --i)
		ifac[i] = (ifac[i + 1] * (i + 1)) % mod;
	for (int i = 0; i <= n; ++i)
		f[n][i] = f[n][i] * fac[n - i] % mod;
	int ans = 0, coff = 1;
	for (int i = k; i <= n; ++i) {
		add(ans, coff * C(i, k) % mod * f[n][i] % mod);
		coff = (mod - coff);
	}
	cout << ans << endl;
}

minmax 容斥

如果我们知道一个子集的 \(\min\),就可以推出这个子集的 \(\max\)

\[\max(S) = \sum\limits_{T \subseteq S} (-1)^{|T|-1} \min(T) \]

如果我们不是求 \(\max\),而是求第 \(k\) 大,这个式子也可以推广到:

\[\text{kth}\max(S) = \sum\limits_{T \subseteq S} (-1)^{|T|-k} \binom{|T|-1}{k-1} \min(T) \]

minmax 容斥一般用来解决对于任意一个子集,他们贡献的 \(\min\) 比较简单,而我们需要求 \(\max\) 的问题。而且更厉害的一点是,这两个式子在期望意义下也是成立的。

minmax 容斥推导过程

其实和二项式反演差不多。我们以下面这个形式为例。我们其实就是要证明右边这个式子中,只有第 \(n-k+1\) 小的元素恰好出现一次,其他元素的系数都是 \(0\)

不妨设第 \(i\) 大的元素为 \(a_i\)\(\min(T)\) 前的系数是一个关于 \(|T|\) 的函数,不妨设为 \(g(|T|)\)。考察每一个 \(a_i\) 的系数,有:

\[\begin{aligned} \text{kth}\max(S)&=\sum\limits_{T \subseteq S} (-1)^{|T|-k} \binom{|T|-1}{k-1} \min(T)\\ &=\sum\limits_{T \subseteq S} g(|T|) \min(T)\\ &=\sum\limits_{i=1}^n a_i\sum_{j=1}^{i}g(j)\binom{i-1}{j-1} \end{aligned} \]

我们现在想要证明,\(a_i\) 的系数 \(\sum\limits_{j=1}^{i}g(j)\binom{i-1}{j-1}\)\(i=k\) 时为 \(1\),其他时候为 \(0\)。设 \(f(i)=[i=k]\),我们想要证明 \(f(i)=\sum\limits_{j=1}^{i}g(j)\binom{i-1}{j-1}\)。不妨换一次元,令 \(i'=i-1,j'=j-1\)。设 \(F(i)=f(i+1)=[i+1=k],G(i)=g(i+1)\),即要证:

\[F(i)=\sum\limits_{j=0}^iG(j)\binom{i}{j} \]

利用二项式反演,得:

\[F(i)=\sum\limits_{j=0}^iG(j)\binom{i}{j} \Leftrightarrow G(i)=\sum\limits_{j=0}^i(-1)^{i-j}\binom{i}{j}F(j) \]

由于我们知道 \(F(j)=[j+1=k]\),也就是只有当 \(j=k-1\) 的时候这一项才不为 \(0\),所以代入得:

\[G(i)=(-1)^{i-(k-1)}\binom{i}{k-1}\\ g(i)=G(i-1)=(-1)^{i-k}\binom{i-1}{k-1} \]

发现恰好就是我们上方对 \(g(i)\) 的定义。于是得证。

posted @ 2025-11-12 21:58  小蛐蛐awa  阅读(6)  评论(0)    收藏  举报