(light oj 1102) Problem Makes Problem (组合数 + 乘法逆元)

题目链接: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

(light oj 1102) Problem Makes Problem (组合数 + 乘法逆元)的相关文章

Light OJ 1102 Problem Makes Problem 组合数

#include <iostream> #include <string> #include <map> #include <vector> #include<algorithm> using namespace std; typedef pair<string,int>PAIR; bool cmp_by_value(const PAIR& p,const PAIR &a) { return p.second<a

Ural 1903 Unidentified Ships 组合数 + 乘法逆元

一开始题意没读懂,英语是硬伤,其实是这道题目真的有点饶人,后来补题,看懂了意思,从n个数中挑出t个,然后第k个必须要在,挑出的t个数要排序成不下降的顺序,然后 原本那个第k个数在这个跳出的t个数当中要在第x的位置 分析:直接找出比第k个数小的数的个数,还有比第k个数大的数的个数,当然啦还有可能存在与第k个数相等的数的个数,唉呀,一开始漏了相等的情况,没看题目案例,真是作死啊,后来全弄好了,那不就是在比它小的里面挑x-1个数字,当然也可以从相等的里面挑了补,然后在比它大的  里面挑t-x个数 当然

【bzoj4517】[Sdoi2016]排列计数 组合数+乘法逆元+dp

题目描述 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i,则称 i 是稳定的.序列恰好有 m 个数是稳定的 满足条件的序列可能很多,序列数对 10^9+7 取模. 输入 第一行一个数 T,表示有 T 组数据. 接下来 T 行,每行两个整数 n.m. T=500000,n≤1000000,m≤1000000 输出 输出 T 行,每行一个数,表示求出的序列数 样例输入 5 1 0 1 1 5 2 100 50 10

Light OJ 1004 - Monkey Banana Problem dp题解

1004 - Monkey Banana Problem PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB You are in the world of mathematics to solve the great "Monkey Banana Problem". It states that, a monkey enters into a diamond shaped two dim

Light OJ 1102

题意: 给你一个数 N , 求分成 K 个数 (可以为 0 ) 的种数: 思路: 类似 在K个抽屉放入 N 个苹果, 不为0, 就是 在 n-1 个空隙中选 m-1个: 为 0, 就可以先在 K 个抽屉一个苹果, 之后类似了: 故答案就是 C(N+K-1, K-1): 数据大, 还控制内存... 按位乘 + 逆元 #include<bits/stdc++.h> using namespace std; typedef int LL; const int maxn = 2000000 + 131

SWJTU2017-6月月赛 G-A Easy Counting Problem[数论][乘法逆元]

传送门:http://www.swjtuoj.cn/problem/2397/ 题解:产生交点的条件为4个点构成四边形对角线产生交点,最大解当产生的交点位置完全不相同时存在.答案为$C_{\text{n}}^4$ 计算组合数时需要使用乘法逆元 代码: 1 #define _CRT_SECURE_NO_DEPRECATE 2 #pragma comment(linker, "/STACK:102400000,102400000") 3 #include<iostream> 4

lightoj 1102 - Problem Makes Problem

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 ar

Light OJ 1067 Combinations (乘法逆元)

Description Given n different objects, you want to take k of them. How many ways to can do it? For example, say there are 4 items; you want to take 2 of them. So, you can do it 6 ways. Take 1, 2 Take 1, 3 Take 1, 4 Take 2, 3 Take 2, 4 Take 3, 4 Input

CodeForces 300C Beautiful Numbers(乘法逆元/费马小定理+组合数公式+快速幂)

C. Beautiful Numbers time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Vitaly is a very weird man. He's got two favorite digits a and b. Vitaly calls a positive integer good, if the decimal