lightoj 1102

1102 - Problem Makes Problem

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=4and 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


PROBLEM SETTER: JANE ALAM JAN

http://www2.chinaedu.com/101resource004/wenjianku/200501/101ktb/lanmu/XF1S0213/XF1S0213.htm

隔板法

思路:组合数学,费马小定理求逆元,快速幂。

用隔板法来求,这个问题可以转化为x1+x2+...xk=n的多元方不同程解的个数,并且xk〉=0;

就是组合数C(n+k-1,k-1) ,那么由费马小定理ap-1==1mod(p);设a-1为a的逆元则(a*a-1*ap-2)=a-1mod(p);

即ap-2=a-1mod(p);C(a,b) =(f(a))/(f(b)*f(a-b));

C(a,b)%p=((f(a))/(f(b)*f(a-b)))%P;其中f(n)表示阶乘。

(a/b)%p=k%p;两边同乘b ----a%p=(k*b)%p;然后两边同乘b-1%p;----a*b-1%p=k%p;

而根据费马小定理ap-2=a-1mod(p);用快速幂求下bp-2%p就可以了。

 1 #include<stdio.h>
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<string.h>
 5 #include<math.h>
 6 #include<queue>
 7 using namespace std;
 8 const long long N=1e9+7;
 9 typedef long long LL;
10 LL quickmi(long long  a,long long  b);
11 LL DP[2*1000005];
12 void Init()
13 {
14     int i,j;
15     DP[0]=1;
16     for(i=1;i<=2000005;i++)
17     {
18         DP[i]=(DP[i-1]*i)%N;
19     }
20 }
21 int main(void)
22 {Init();
23     int i,j,k,p,q;
24     scanf("%d",&k);
25     for(i=1;i<=k;i++)
26     {
27         scanf("%d %d",&p,&q);
28         LL ans=quickmi(DP[q-1]*DP[p]%N,N-2);
29         printf("Case %d: ",i);
30         printf("%lld
",DP[p+q-1]*ans%N);
31     }
32     return 0;
33 }
34 
35 LL quickmi(long long  a,long long  b)
36 {
37     LL sum=1;
38     while(b)
39     {
40         if(b&1)
41        sum=(sum*a)%(N);
42        a=(a*a)%N;
43        b/=2;
44     }
45     return sum;
46 }
油!油!you@
原文地址:https://www.cnblogs.com/zzuli2sjy/p/5223002.html