题目描述
Chino的数学很差,因此Cocoa非常担心。今天,Cocoa要教Chino解不定方程。
众所周知,不定方程的解有0个或者若干个。
给出方程:
Cocoa想知道这个不定方程的正整数解和非负整数解各有几个。
题目对Chino来说太难啦,你能帮一帮Chino吗?
输入描述:
两个正整数m, n
输出描述:
题目要求的答案,即正整数解的个数和非负整数解的个数 。由于答案可能会很大,你只需要输出答案 mod(109 + 7) 即可。
示例1
输入
4 7
输出
20 120
思路:
利用挡板思想。
(1)正整数解:
可以抽象成有n-1个挡板,从中选m-1个,将物品分成m部分,即为C(n-1,m-1);
(2) 非负整数解:
因为有的划分部分可能为空,所以共有n+m-1个挡板,从中选m-1个,将物品分成m部分,即为C(n+m-1,m-1);
C(n,m)的公式为:n!/(m!*(n-m)!);
分母部分的两个数需要求出逆元,然后直接相乘即为答案。
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int maxn=2*1e6+5;
ll ji[maxn];
ll m,n;
ll quick(ll a,ll b)
{
ll ans=1;
while(b)
{
if(b%2) ans=ans*a%mod;
a=a*a%mod;
b/=2;
}
return ans;
}
void solji()
{
ji[0]=1;
for (int i=1;i<maxn;i++) {
ji[i]=ji[i-1]*i%mod;
}
}
int main()
{
solji();
scanf("%lld%lld",&m,&n);
ll n1=n-1,m1=m-1;
ll n2=n+m-1,m2=m-1;
ll inv1=quick(ji[m1],mod-2);
ll inv2=quick(ji[n1-m1],mod-2);
ll ans1=ji[n1]*inv1%mod*inv2%mod;
ll inv3=quick(ji[m2],mod-2);
ll inv4=quick(ji[n2-m2],mod-2);
ll ans2=ji[n2]*inv3%mod*inv4%mod;
printf("%lld %lld\n",ans1,ans2);
return 0;
}