计算组合数有许多方法,我先是分解质因数,但是这样效率非常低,1700ms。
然后求逆元,求解,时间复杂度为o(N).这个模数是质数,不用考虑逆元无解情况。
#include<iostream>
#include<cstdio>
#define LL long long
using namespace std;
LL K=20100403;
LL x,y;
void exgcd(LL a,LL b)
{
if(b==0)
{
x=1;y=0;
return ;
}
exgcd(b,a%b);
LL x1=y;
LL y1=x-a/b*y;
x=x1;y=y1;
}
void work(LL b,LL m)
{
exgcd(b,m);
while(x<0)x+=m;
x%=m;
}
LL calc(int n,int m)
{
LL fz=1;
for(int i=n+1;i<=n+m;i++)
fz=((LL)(i%K)*fz)%K;
LL fm=1;
for(int i=2;i<=m;i++)
fm=((LL)(i%K)*fm)%K;
work(fm,K);
fz*=x;fz%=K;
return fz;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
LL ans1=calc(n,m);
LL ans2=calc(n+1,m-1);
ans1-=ans2;
while(ans1<0) ans1+=K;
ans1%=K;
cout<<ans1;
return 0;
}