提高历练地-其他数学问题

P1641 [SCOI2010]生成字符串
题目描述

lxhgww最近接到了一个生成字符串的任务,任务需要他把n个1和m个0组成字符串,但是任务还要求在组成的字符串中,在任意的前k个字符中,1的个数不能少于0的个数。现在lxhgww想要知道满足要求的字符串共有多少个,聪明的程序员们,你们能帮助他吗?

输入格式

输入数据是一行,包括2个数字n和m

输出格式

输出数据是一行,包括1个数字,表示满足要求的字符串数目,这个数可能会很大,只需输出这个数除以20100403的余数

输入输出样例

输入 #1 复制
2 2
输出 #1 复制
2
说明/提示
limitation

每点2秒

对于30%的数据,保证1<=m<=n<=1000

对于100%的数据,保证1<=m<=n<=1000000

费马小定理
费马小定理是数论中的一个定理:假如a是一个整数,p是一个质数,那么a^p-a是p的倍数
在这里插入图片描述
如果a不是p的倍数,这个定理也可以写成
在这里插入图片描述
若a与p互质,且p是质数时,a(p-1)≡1 ,并且,a-1也是a的逆元
有:
a(p-1)=1=a-1a
a(p-1)=a-1a
a(p-2)=a-1
即:
C(n,m)=( n*(n-1)* … * (n-m+1) ) / ( m! )=( n*(n-1)* … * (n-m+1) ) * (m!)(p-2)
= n! * (m! * (n-m)!)20100403

#include<bits/stdc++.h>
#define MAX_INT  ((unsigned)(-1)>>1)
#define MIN_INT  (~MAX_INT)
#define pi (4*atan(1.0))
#define ll long long
#define inf 0x3f3f3f3f
#define infmax 0x3f3f3f3f3f3f3f3f
using namespace std;
int read()
{
    int c=0;int flag=1;
    char s;
    while((s=getchar())>'9'||s<'0')if(s=='-')flag=-1;
    c=s-'0';
    while((s=getchar())<='9'&&s>='0') c=c*10+s-'0';
    return c*flag;
}
ll mod=20100403;
ll c(ll m,ll n)
{
    ll ans1=1,ans2=1,ans3=1;
    for(ll i=m;i>(m-n);i--){
        ans1=(ans1*i)%mod;
        ans1%=mod;
    }
    for(ll i=1;i<=n;i++){
        ans2=(ans2*i)%mod;
        ans2%=mod;
    }
    ll p=mod-2;
    while(p>0){
        if(p%2==1) ans3=(ans3*ans2)%mod;
        ans2=(ans2*ans2) %mod;
        p/=2;
    }
    return (ans1*ans3)%mod;
}
int main(void)
{
    ll a,b;
    cin>>a>>b;
    cout<<(c(a+b,a)-c(b+a,a+1)+mod)%mod;
    return 0;
}
发布了30 篇原创文章 · 获赞 2 · 访问量 1045

猜你喜欢

转载自blog.csdn.net/weixin_45662558/article/details/104039468
今日推荐