例题:F 莫卡的手套
23级算法 E1 F题
时间限制:1000ms 内存限制:65536kb
题目描述
莫卡购买了 nn 对不同的手套,每对手套由左右各一只组成。
莫卡想知道,如果自己从中随机取出 mm 只手套,mm 只手套恰好包含 kk 对手套的情况有多少种。两种取出的情况不同,当且仅当两种情况取出的手套中存在不同的手套(同一对手套的左右手也视为不同的手套)。
输入
第一行包含一个正整数 tt,代表测试用例组数。
接下来是 tt 组测试用例。对于每组测试用例,一共一行。
第一行包含三个正整数 n,m,kn,m,k,代表手套数量,随机取出的手套数和目标对数。
对于全部数据,保证有 1≤t≤105,1≤n≤1000,1≤m≤2×n,1≤k≤n1≤t≤105,1≤n≤1000,1≤m≤2×n,1≤k≤n。
输出
对于每组测试数据,输出一个整数,代表可能的情况数量对 109+7109+7 取模的结果。
输入样例
2
5 6 2
5 1 5
输出样例
120
0
my代码
#include <stdio.h>
long long qmi(long long mom, long long b, long long mod);
int main() {
int t;
long long MOD = 1000000000+7;
scanf("%d", &t);
for(int i=0; i<t; i++){
long long x;
long long n, m, k;
scanf("%lld%lld%lld", &n, &m, &k);
if(m < 2*k || m-k>n){
printf("0\n");
}else{
long long mom=1, son=1;
// 分母
for(long long j=k; j>=1; j--){
mom *= j;
mom %= MOD;
}
for(long long j=m-2*k; j>=1; j--){
mom *= j;
mom %= MOD;
}
for(long long j=n-m+k; j>=1; j--){
mom *= j;
mom %= MOD;
}
x = qmi(mom, MOD-2, MOD); //x是mom在mod MOD下的逆元
// 分子
for(long long j=n; j>=1; j--){
son *= j;
son %= MOD;
}
for(long long j=m-2*k; j>=1; j--){
son *= 2;
son %= MOD;
}
long long ans = ((son % MOD) * (x % MOD)) % MOD;
printf ("%lld\n", ans);
}
}
return 0;
}
long long qmi(long long mom, long long b, long long mod){
long long res = 1;
while(b){
if(b & 1) res = res * mom % mod;
b >>= 1;
mom = mom * mom % mod;
}
return res;
}