题目链接:http://lightoj.com/volume_showproblem.php?problem=1102
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个数的方案数.
分析:显然这个就是一个组合公式,隔板法。可以把问题转化为x1+x2+…..xk = n 这个多元一次方程上。然后这个解就是C(n+k-1,k-1)
这道题n,k范围都是1e6。
我们可以预处理出阶乘,然后求对应的组合数,注意这里需要取Mod,用下逆元就好啦.
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<math.h> #include<queue> #include<stack> #include <map> #include <string> #include <vector> #include<iostream> using namespace std; #define N 3000006 #define INF 0x3f3f3f3f #define LL long long #define mod 1000000007 LL arr[N]; void Init() { arr[0] = 1; for(int i=1;i<=N;i++) { arr[i] = (arr[i-1]*i)%mod; arr[i] %= mod; } } LL quick(LL a, LL b) { a = a%mod; LL ans = 1; while(b) { if(b&1) ans = ans*a%mod; a = a*a%mod; b /= 2; } return ans %mod; } LL solve(LL a, LL b, LL c) { if(b>a) return 0; return arr[a] * (quick(arr[b] * arr[a-b],c-2)) %mod;///利用乘法逆元 } int main() { Init(); int T; int con=1; scanf("%d",&T); while(T--) { LL n,k; scanf("%lld %lld",&n,&k); printf("Case %d: %lld\n",con++,solve(n+k-1,k-1,mod));///Cn-k+1(k-1); } return 0; }
时间: 2024-10-21 12:21:56