1102 - Problem Makes Problem
PDF (English) | Statistics | Forum |
Time Limit: 2 second(s) | Memory Limit: 32 MB |
As I am fond of making easier problems, I discovered a problem. Actually, the problem is 'how can you make n by adding k non-negative integers?' I think a small example will make things clear. Suppose n=4 and k=3. There are 15 solutions. They are
1. 0 0 4
2. 0 1 3
3. 0 2 2
4. 0 3 1
5. 0 4 0
6. 1 0 3
7. 1 1 2
8. 1 2 1
9. 1 3 0
10. 2 0 2
11. 2 1 1
12. 2 2 0
13. 3 0 1
14. 3 1 0
15. 4 0 0
As I have already told you that I use to make problems easier, so, you don't have to find the actual result. You should report the result modulo 1000,000,007.
Input
Input starts with an integer T (≤ 25000), denoting the number of test cases.
Each case contains two integer n (0 ≤ n ≤ 106) and k (1 ≤ k ≤ 106).
Output
For each case, print the case number and the result modulo 1000000007.
Sample Input | Output for Sample Input |
4 4 3 3 5 1000 3 1000 5 | Case 1: 15 Case 2: 35 Case 3: 501501 Case 4: 84793457 |
题意:
给你两个数n和k(n,k<=1e6),求把数n分解成 k个[0,n]的数 之和的方法总数(k个数的排列位置不同也算)。
思路:
隔板法。
我们将n分成k个部分,因为里面有些部分可能为0,如果让每个部分至少为1,那么就先把n加上k(每一部分至少为1)。
然后就相当于在n+k个数的n+k-1个空隙中选择k-1个隔板,答案就是C(n+k-1,k-1)。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mo=1000000007;
const int maxn=2e6+5;
ll dp[maxn];
int n,m,k;
void init()
{
int i,j;
dp[0]=1;
for(int i=1;i<maxn;i++)
{
dp[i]=(dp[i-1]*i)%mo;
}
}
ll power(ll a,ll n)
{
ll sum=1;
while(n)
{
if(n&1) sum=sum*a%mo;
a=(a*a)%mo;
n>>=1;
}
return sum;
}
int main()
{
init();
int T,cas=1;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
ll ans=power(dp[m-1]*dp[n]%mo,mo-2);
ans=dp[n+m-1]*ans%mo;
printf("Case %d: %lld\n",cas++,ans);
}
return 0;
}