Gym - 101864E E - Diverse Group(费马小定理求乘法逆元 求 组合数 取模 + 快速幂)

E - Diverse Group

It’s the year 3018 and you are the head of the Bioinformation Articulation in Cosmic Space (BACS) program at NASA. Under this program, NASA has decided to send K humans to planet Naboo. The whole of humanity is very excited about this and everyone wants to be a part of this voyage. But alas, there is only room for K people. Now, there are N regions in planet Earth. NASA asked each of these regions to compile a list of M people from that region who would be fit for this journey. The listing is complete and now you have the N lists at your disposal (one for each region, each containing M people). Among these N*M people, you want to select K people for this journey. But you want to make the selected group as diverse as possible. Therefore, you have decided not to select two person from the same region. Being a math enthusiast, you want to know how many different ways you can make this group. Two groups are different if there is someone who is in one group but not in the other.

 

Input Specifications

The first line contains a positive integer T (T ​≤ 1000) denoting the number of test cases. In each of the following T lines, there will be three space separated integers N, M & K where N denotes the number of regions, M denotes the number of people from that region and K denotes the number of people who will sent to planet Naboo.

 

Constraints

2 ≤ N,M ≤ 10000000

1 ≤ K ≤ N*M

 

Outputput Specification:

For each case, print the number of ways you can make that group. Since the answer can be rather big, print the answer modulo 1000000007 (10​^9​ + 7)​.

 

Input

5

2 2 1

2 3 2

3 2 5

4 2 3

5 4 4

Output

4

9

0

32

1280

 

题意:给你三个整数 N,M,K , 大概可以理解为   N 个队,每一队有 M 个人,然后需要 取 K 个人 出来,但是 每一个队 只能取一个人 或者  不取。 问最后 有多少种 方案。 最后对  1e9 + 7 取模。

思路:其实这个题思路不难,  答案就是   C(N,K) * M^K。 主要是算 组合数取模。这里 组合数取模 用的 乘法逆元 计算的。

关于乘法逆元求组合数取模。。 最后就是  M^K,  很明显  用快速幂。

AC代码:

#include<cstdio>

using namespace std;

typedef long long LL;
const LL maxn = 1e7 + 100,mod = 1e9 + 7;

LL Jc[maxn];

void calJc()    //求maxn以内的数的阶乘
{
    Jc[0] = Jc[1] = 1;
    for(LL i = 2; i < maxn; i++)
        Jc[i] = Jc[i - 1] * i % mod;
}

//费马小定理求逆元
LL pow(LL a, LL n, LL p)    //快速幂 a^n % p
{
    LL ans = 1;
    while(n)
    {
        if(n & 1)
            ans = ans * a % p;
        a = a * a % p;
        n >>= 1;
    }
    return ans;
}

LL niYuan(LL a, LL b)   //费马小定理求逆元
{
    return pow(a, b - 2, b);
}

LL C(LL a, LL b)    //计算C(a, b)
{
    return Jc[a] * niYuan(Jc[b], mod) % mod
           * niYuan(Jc[a - b], mod) % mod;
}

int main()
{
    int t;
    scanf("%d",&t);
    calJc();
    while(t --)
    {
        LL n,m,k;
        scanf("%I64d%I64d%I64d",&n,&m,&k);
        if(n >= k) printf("%I64d\n",C(n,k) * pow(m,k,mod) % mod);
        else printf("0\n");
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值