1856: [Scoi2010]字符串
Time Limit: 5 Sec Memory Limit: 64 MB
Submit: 1763 Solved: 1002
[Submit][Status][Discuss]Description
lxhgww最近接到了一个生成字符串的任务,任务需要他把n个1和m个0组成字符串,但是任务还要求在组成的字符串中,在任意的前k个字符中,1的个数不能少于0的个数。现在lxhgww想要知道满足要求的字符串共有多少个,聪明的程序员们,你们能帮助他吗?Input
输入数据是一行,包括2个数字n和mOutput
输出数据是一行,包括1个数字,表示满足要求的字符串数目,这个数可能会很大,只需输出这个数除以20100403的余数Sample Input
2 2
Sample Output
2
HINT
【数据范围】
对于30%的数据,保证1<=m<=n<=1000
对于100%的数据,保证1<=m<=n<=1000000Source
题解
总方案数是 $inom{n+m}{n}$ , 不合法方案数 $inom{n+m}{m-1}$ , 推出阶乘表之后就可以求了
还记得某BZOJ的网格...就是这个题的高精版...
参考代码
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <iostream> 5 #include <algorithm> 6 7 const int MAXN=2e6+10; 8 const int MOD=20100403; 9 10 int n,m; 11 int fact[MAXN]; 12 13 int C(int,int); 14 int Pow(int,int,int); 15 16 int main(){ 17 scanf("%d%d",&n,&m); 18 fact[0]=1; 19 for(int i=1;i<=n+m;i++){ 20 fact[i]=1ll*fact[i-1]*i%MOD; 21 } 22 printf("%d ",int(((C(n+m,n)-C(n+m,m-1))%MOD+MOD)%MOD)); 23 return 0; 24 } 25 26 inline int C(int n,int m){ 27 return 1ll*fact[n]*Pow(fact[m],MOD-2,MOD)%MOD*Pow(fact[n-m],MOD-2,MOD)%MOD; 28 } 29 30 inline int Pow(int a,int n,int p){ 31 int ans=1; 32 while(n>0){ 33 if((n&1)!=0){ 34 ans=1ll*ans*a%p; 35 } 36 a=1ll*a*a%p; 37 n>>=1; 38 } 39 return ans; 40 }