问题描述
给出 n , m ( n ≥ m ) n,m(n\ge m) n,m(n≥m),求长度为 n + m n+m n+m含有 n n n个 1 1 1和 m m m个 0 0 0且其任意一个前缀满足前缀中 1 1 1的数量大于等于 0 0 0的数量的字符串的数量,对 20100403 20100403 20100403取模。
无约束条件的方案数为
C
(
n
+
m
,
m
)
C(n+m,m)
C(n+m,m)。
把
0
0
0改做
−
1
-1
−1,那么题意转换为,字符串任意一个前缀的前缀和都
≥
0
\ge 0
≥0。
充分性
考虑一个不满足约束条件的字符串,找到其第一个前缀和为 − 1 -1 −1的位置,设其前面有 x x x个 1 1 1和 − 1 -1 −1,则其后面有 n − x n-x n−x个 1 1 1和 m − 1 − x m-1-x m−1−x个 − 1 -1 −1,将这个位置后面的 1 1 1改为 − 1 -1 −1, − 1 -1 −1改为 1 1 1,那么总的 1 1 1的数量变为 x + m − 1 − x = m − 1 x+m-1-x=m-1 x+m−1−x=m−1个,总的 − 1 -1 −1的数量变为 x + 1 + ( n − x ) = n + 1 x+1+(n-x)=n+1 x+1+(n−x)=n+1个,于是计算不满足约束条件的方案数为 C ( n + m , m − 1 ) C(n+m,m-1) C(n+m,m−1)。
必要性
令
f
(
n
,
m
)
f(n,m)
f(n,m)表示含有
n
n
n个
1
1
1,
m
m
m个
−
1
-1
−1的字符串。
f
(
m
+
1
,
n
−
1
)
f(m+1,n-1)
f(m+1,n−1)是否可以根据充分性唯一还原出一个不合法的
f
(
n
,
m
)
f(n,m)
f(n,m),取决于其是否含有前缀和
−
1
-1
−1。
当
n
≥
m
n\ge m
n≥m,
(
m
−
1
)
∗
1
+
(
n
+
1
)
∗
−
1
≥
−
2
(m-1)*1+(n+1)*-1\ge -2
(m−1)∗1+(n+1)∗−1≥−2,显然必含有前缀和为
−
1
-1
−1的前缀。
又题设有约束
n
≥
m
n\ge m
n≥m,故结论成立。
注:当
n
=
m
n=m
n=m时,
C
(
2
∗
n
,
n
)
−
C
(
2
∗
n
,
n
−
1
)
C(2*n,n)-C(2*n,n-1)
C(2∗n,n)−C(2∗n,n−1)为卡特兰数,本题实际为卡特兰数的一个推广。
#include<bits/stdc++.h>
using namespace std;
const int N=2e6+5,mod=20100403;
typedef long long ll;
ll f[N],invf[N];
ll C(ll n,ll m)
{
return f[n]*invf[n-m]%mod*invf[m]%mod;
}
int main()
{
f[0]=f[1]=invf[0]=invf[1]=1;
for(int i=2;i<N;i++) f[i]=f[i-1]*i%mod,invf[i]=(mod-mod/i)*invf[mod%i]%mod;
for(int i=2;i<N;i++) invf[i]=invf[i-1]*invf[i]%mod;
int n,m;
scanf("%d%d",&n,&m);
printf("%lld\n",(C(n+m,m)-C(n+m,m-1)+mod)%mod);
}