bzoj 1856: [Scoi2010]字符串
1856: [Scoi2010]字符串
Time Limit: 5 Sec Memory Limit: 64 MBDescription
lxhgww最近接到了一个生成字符串的任务,任务需要他把n个1和m个0组成字符串,但是任务还要求在组成的字符串中,在任意的前k个字符中,1的个数不能少于0的个数。现在lxhgww想要知道满足要求的字符串共有多少个,聪明的程序员们,你们能帮助他吗?
Input
输入数据是一行,包括2个数字n和m
Output
输出数据是一行,包括1个数字,表示满足要求的字符串数目,这个数可能会很大,只需输出这个数除以20100403的余数
Sample Input
2 2
Sample Output
2
HINT
【数据范围】
对于30%的数据,保证1<=m<=n<=1000
对于100%的数据,保证1<=m<=n<=1000000
Source
Code:
#include<cstdio> #include<algorithm> #include<iostream> #include<cstring> #define MOD 20100403 using namespace std; long long x,y,n,m,p,f[2000008],a,b,x1,y1,ans; void exgcd(long long a,long long b){ if(b==0){ x=1,y=0; return; } exgcd(b,a%b); long long t=x; x=y; y=t-a/b*y; } void init(){ f[0]=1; for(int i=1;i<=n+m;i++) f[i]=f[i-1]*i%MOD; } int main(){ scanf("%lld%lld",&n,&m); init(); a=n+m; b=m; long long gay1=1,gay2=1; for(int i=1;i<=b;i++){ exgcd(i,MOD); x=(x+MOD)%MOD; gay1=gay1*x%MOD; if(i==b-1) x1=gay1; } for(int i=1;i<=a-b;i++){ exgcd(i,MOD); x=(x+MOD)%MOD; gay2=gay2*x%MOD; } exgcd(a-b+1,MOD); x=(x+MOD)%MOD; y1=gay2*x%MOD; ans=(f[a]*gay1%MOD*gay2%MOD-f[a]*x1%MOD*y1%MOD+MOD)%MOD; printf("%lld",ans); }