思路
前置题:https://www.acwing.com/problem/content/1310/
不等式
$$ 1 \le a_1 + a_2 + \cdots + a_m \le n, a_i \in [0, n] $$
的解与以下方程的解一一对应:
$$ a_1 + a_2 + \cdots + a_m + a_{m + 1} = n, \forall i \in [1, m], a_i \in [0, n], a_{m + 1} \in [0, n - 1] $$
即对于任意一组不等式解 $a_1 + a_2 + \cdots + a_m = k \in [1, n]$,令 $a_{m + 1} = n - k \in [0, n - 1]$ 就得到一组方程的解。反之,任意一组方程的解,去掉 $a_{m + 1}$ 就变为一组不等式的解。
若 $a_{m + 1} = n$,则上述方程只有一组解,即 $a_1, a_2, \cdots, a_m = 0, a_{m + 1} = n$。
若 $\forall i \in [1, m + 1], a_i \in [0, n]$,令 $b_i = a_i + 1 \in [1, n + 1]$,则以下方程的解与原方程的解一一对应:
$$ b_1 + b_2 + \cdots + b_m + b_{m + 1} = n + m + 1 $$
而上述方程解的个数可用隔板法(见前置题或本文末尾的例题)求出,为 $C_{n + m}^{m}$。
因此答案是 $C_{n + m}^{m}$,减去 $a_{m + 1} = n$ 时的一组解。
MOD = int(1e6) + 3
def mpow(a, n, m):
r = 1 % m
while n:
if n & 1: r = r * a % m
a = a * a % m
n >>= 1
return r
def C(n, m):
res = 1
for i, j in zip(range(n, -1, -1), range(1, m + 1)):
res = res * i * mpow(j, MOD - 2, MOD) % MOD
return res
n, m = map(int, input().split())
print((C(n + m, m) - 1 + MOD) % MOD)
隔板法
太强了orz
为什么要将 “a1+a2+⋯+am+am+1=n” 转化为 “b1+b2+⋯+bm+bm+1=n+m+1” ?
方便放隔板
好的谢谢
因为a1 + a2+a3+..am+ 1 = n,那我Cn-1,m是不是也可以哦?
不行,要转换成至少放一个。
明白哩
美琴不仅人长得美,写得题解也很美