Loading

组合意义天地灭。

部分习题选自 BIJECTIVE PROOF PROBLEMS,部分来自网上。
1.

\[\sum\limits_{i=0}^n \binom{k+i}{i}=\binom{n+k+1}{n} \]

考虑左边在干啥,相当于枚举最后一个位置为 \(k + i + 1\) 然后前面选 \(k\) 个,于是就是 \(n + k + 1\)\(k + 1\) 个的方案数。
2.

\[\sum\limits_{i=k}^n \binom{i}{k}=\binom{n+1}{k+1} \]

类似证法。
3.

\[\sum\limits_{i=0}^n i\binom{n}{i}=n2^{n-1} \]

考虑 \(i = \binom{i}{1}\),于是 LHS 相当于选 \(i\) 个,再选一个特殊的。RHS 是先枚举这个特殊的,剩下乱填,是一样的。
4.

\[\sum\limits_{i=0}^n i^2\binom{n}{i}=n(n+1)2^{n-2} \]

类似证法,考虑 \(i^2 = \binom{i}{1} + 2\binom{i}{2}\)
5.

\[\sum\limits_{i=0}^{n}\binom{n-i}{i}=F_{n+1} \]

\(F\) 为斐波那契数列。

归纳固然可证,然而考虑用 \(1\)\(2\) 凑出 \(n\) 但是不同的排列重复计数,显然是 \(F_{n}\),枚举 \(2\) 的个数 \(i\)\(1\) 就是插板,\(\binom{n - 2i + i}{i}=\binom{n-i}{i}\)
6.

\[\sum\limits_{k=0}^n \binom{2k}{k}\binom{2n-2k}{n-k}=4^n \]

这个很牛。考虑组合意义本质是在构一个双射。

有个引理:
\((0, 0)\) 开始走,每次走到 \((x + 1, y - 1)\)\((x + 1, y + 1)\),走 \(2n - 1\) 步,要求始终保持 \(y \ge 0\) 的方案数为 \(\dbinom{2n-1}{n}\)

Proof: 首先最后的高度 \(h\) 一定是一个奇数,且 \(h \ge 1\),设 \(h = 2r+1\),向上走了 \(a\) 步,向下走了 \(b\) 步,则 \(a + b = 2n - 1, a - b = h \Rightarrow a = n + r\),乱填方案为 \(\dbinom{2n-1}{a} = \dbinom{2n-1}{n+r}\),然后考虑经过 \(y = -1\) 的方案数,记第一次到达 \(y = -1\)\(x = k\),将前面的路径关于 \(y = -1\) 对称,两种路径构成一个双射,于是变成了 \((-2, 0)\)\((2n - 1, h)\) 的方案数,同理可得方案数为 \(\dbinom{2n-1}{n+r+1}\)

然后枚举 \(r\),总方案数为 \(\large{\sum\limits_{r=0}^{n-1} \binom{2n-1}{n+r} - \binom{2n-1}{n+r+1}}\),裂项得到 \(\dbinom{2n-1}{n}\)

上面是基础的反射容斥。

考虑原问题转化成格路计数,从 \((0, 0)\) 开始走,每次走到 \((x + 1, y - 1)\)\((x + 1, y + 1)\),走 \(2n\) 步,方案数为 \(4^n\),另外考虑最后一个到 \(y = 0\) 的位置,此时的 \(x\) 记为 \(2k\),前面的方案数就是 \(\dbinom{2k}{k}\),后面的方案数,由于其不会重新到 \(y = 0\),只能是 \(y\) 恒大于/小于 \(0\),由于对称性只考虑 \(y\) 恒大于 \(0\),最后方案数 \(\times 2\)。那么第一步肯定是确定的向上走,来到 \(y = 1\),要从 \((2k, 1)\) 开始走 \(2n - 2k - 1\) 步并始终保持 \(y \ge 1\),那么根据引理,方案数是 \(\dbinom{2n-2k-1}{n-k}\),由于 \(2\dbinom{2n-1}{n}=\dbinom{2n}{n}\),因为 \(\dbinom{2n}{n}=\dbinom{2n-1}{n-1}+\dbinom{2n-1}{n}\), 于是这部分方案数为 \(\dbinom{2(n-k)}{n-k}\)。得证。

\[\sum\limits_{k=0}^m \dbinom{m+k}{k}2^{m-k}=2^{2m} \]

考虑一个 \(01\) 序列,RHS 就是长度为 \(2m\)\(01\) 序列个数。
对于 LHS,\(k=m\) 时代表 \(01\) 出现次数均为 \(m\),显然方案数为 \(\binom{2m}{m}\),对于 \(k < m\),序列中肯定有众数,其出现次数至少为 \(m+1\),枚举其第 \(m+1\) 次出现的位置 \(m+1+k\),那么方案数就是 \(\binom{m+k}{k}2^{m-k}\)

\[F_{2n}=\sum\limits_{i=0}^n F_i\dbinom{n}{i} \]

其中 \(F\) 为斐波那契数列。
考虑 \(F_n\) 的组合意义是用 \(x + 1\)\(x + 2\)\(n\) 步。
考虑前 \(n\) 步有 \(i\)\(x + 1\),总共走了 \(i + 2(n - i) = 2n - i\),剩下 \(i\) 需要走,于是是 \(F_i\)

下面是应用:

[ARC212C] ABS Ball

首先去绝对值,如果 \(a_i < b_i\)\(\text{swap}(a_i, b_i)\) 之后会得到相同的结果,于是钦定 \(a_i > b_i\),最后答案乘上 \(2^m\)

那么就变成了

\[\large{\sum\prod a_i - b_i} \]

考虑这个就是每个盒子里的红点和蓝点匹配,剩下的红点。

剩下的红点个数 \(a_i - b_i = \dbinom{a_i - b_i}{1}\),于是相当于从每个箱子里剩下的点选一个。枚举匹配的点数之和 \(p\),那么剩下 \(n-2p\) 个点。

首先把匹配分配到盒子里,那么就是一个插板,方案数为 \(\dbinom{p+m-1}{m-1}\)。然后剩下的点分到 \(m\) 个箱子里也是一个插板。

然后,注意到每个盒子只会选一个球,我们考虑选的这个球和下一个球直接隔了恰好一个板,且球也把盒子分成了两部分。于是发现球就等效于一个板,也就是插 \(2m-1\) 个板,第奇数个板代表一个球。

于是在剩下的 \(n-2p-m\) 个球里插 \(2m-1\) 个板。方案数为 \(\dbinom{n-2p+m-1}{2m-1}\)

\[Ans=2^m\sum_p\dbinom{p+m-1}{m-1}\dbinom{n-2p+m-1}{m-1} \]

时间复杂度 \(\mathcal{O}(n+m)\)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
// typedef __int128 i128;
typedef pair<int, int> pii;
const int N = 2e7 + 10, mod = 998244353;
template<typename T>
void dbg(const T &t) { cout << t << endl; }
template<typename Type, typename... Types>
void dbg(const Type& arg, const Types&... args) {
    cout << arg << ' ';
    dbg(args...);
}
namespace Loop1st {
int n, m;
ull pw[N], fac[N], ifac[N], ans;
ull qpow(ull a, ull b) {
    ull res = 1;
    for (; b; b >>= 1, a = a * a % mod) if (b & 1) res = res * a % mod;
    return res;
}
ull C(int n, int m) {
    if (n < m || n < 0 || m < 0) return 0llu;
    return fac[n] * ifac[m] % mod * ifac[n - m] % mod;
}
void main() {
    cin >> n >> m;
    fac[0] = ifac[0] = pw[0] = 1;
    for (int i = 1; i <= n + m; i++) fac[i] = fac[i - 1] * i % mod, pw[i] = pw[i - 1] * 2 % mod;
    ifac[n + m] = qpow(fac[n + m], mod - 2);
    for (int i = n + m - 1; i; i--) ifac[i] = ifac[i + 1] * (i + 1) % mod;
    for (int p = 0; p <= (n + m - 1) / 2; p++) {
        ans = (ans + C(p + m - 1, m - 1) * C(n - p - p + m - 1, m + m - 1) % mod) % mod;
    }
    cout << pw[m] * ans % mod << '\n';
}

}
int main() {
    // freopen("data.in", "r", stdin);
    // freopen("data.out", "w", stdout);
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    int T = 1;
    // cin >> T;
    while (T--) Loop1st::main();
    return 0;
}
posted @ 2025-12-23 21:35  循环一号  阅读(72)  评论(0)    收藏  举报