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
",( (C(n+m, n)-C(n+m,n+1))%mod+mod) %mod );
    }
    return 0;
}
原文地址:https://www.cnblogs.com/wuwangchuxin0924/p/6413271.html