String
String |
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) |
Total Submission(s): 89 Accepted Submission(s): 45 |
Problem Description
Recently, lxhgww received a task : to generate strings contain '0's and '1's only, in which '0' appears exactly m times, '1' appears exactly n times. Also, any prefix string of it must satisfy the situation that the number of 1's can not be smaller than the number of 0's . But he can't calculate the number of satisfied strings. Can you help him?
|
Input
T(T<=100) in the first line is the case number.
Each case contains two numbers n and m( 1 <= m <= n <= 1000000 ). |
Output
Output the number of satisfied strings % 20100501.
|
Sample Input
1 2 2 |
Sample Output
2 |
Author
lxhgww
|
Source
HDOJ Monthly Contest – 2010.05.01
|
Recommend
lcy
|
/* 题意:一个序列由m个0和n个1组成,每一个前缀1的个数都大于等于0的个数,给你n,m让你输出有多少种可能 初步思路:递推画一个坐标就可以发现,n为横坐标,m为纵坐标,dp[i][j]为有i个0,j个1组成的序列的种类 得到递推公式 dp[i][j]=dp[i][j-1]+dp[i-1][j-1] 不过这么做是不行的,1e12 的数组根本开不了. #补充:只需要记录,m-1行和m行的数据用矩阵快速幂搞出来,不行保存m-1行的必须再保存m-2行 #错误:上面这种思想推得错误了,没有组合计数,加上每次状态转移的时候都进行排列组合得到dp[i][j]=C(j+i, j)-C(j+i,j+1)。 */ #include<bits/stdc++.h> #define mod 20100501 using namespace std; /*************************组合数模板***************************/ #define ll long long #define MAXN 20000007 bool mark[MAXN]; int prime[MAXN/3],primecnt,sum[MAXN/3]; void fun()//质因子 { primecnt=0; memset(mark,false,sizeof(mark)); mark[0]=mark[1]=true; for(int i=2; i<=MAXN; i++) { if(!mark[i]) { for(int j=i+i; j<=MAXN; j+=i) mark[j]=true; prime[primecnt++]=i; } } return ; } ll power(ll a,ll b)//快速幂 { ll ans=1; while(b) { if(b&1) ans=(ans*a)%mod; a=(a*a)%mod; b>>=1; } return ans; } ll yzs(ll x,ll y) { ll ans=x/y; if(x<y) return ans; return ans+=yzs(x/y,y); } ll C(ll n,ll m) { if(n<m) return 0; ll ans=1; for(int i=0; i<primecnt; i++) { if(prime[i]>n) break; ans*=power(prime[i],yzs(n,prime[i])-yzs(m,prime[i])-yzs(n-m,prime[i])); ans%=mod; } return ans; } /*************************组合数模板***************************/ ll t,n,m; int main(){ // freopen("in.txt","r",stdin); fun(); scanf("%lld",&t); while(t--){ scanf("%lld%lld",&n,&m); printf("%lld\n",( (C(n+m, n)-C(n+m,n+1))%mod+mod) %mod ); } return 0; }
我每天都在努力,只是想证明我是认真的活着.