题解:SP28304 ADATEAMS - Ada and Teams
Ryzen_9_9950X3D · · 题解
这是一个排列组合问题。
事先声明
如果你不懂排列是什么,请左转这个链接。\ 如果你不懂组合是什么,请左转这个链接。\ 如果你不懂乘法逆元是什么,请左转这个链接。
思路
由题面可知,我们需要求出
而且,我们还要在每一所学校的
由思路到实现
我们试图直接实现的时候,会发现:经过 Deepseek の 提醒经过思考,我们能够想到一种很新的实现的方式:乘法逆元。
首先,我们处理
代码
想抄代码的看过来:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define MOD 1000000007
int inv[1000005],fact[1000005],invfact[1000005];
int C(int n,int k)
{
if(k < 0 || k > n) return 0;
return 1LL * fact[n] * invfact[k] % MOD * invfact[n - k] % MOD;
}
int ksm(int n,int m)
{
int ans = 1;
while(m)
{
if(m & 1) ans = (ans * n) % MOD;
n = (n * n) % MOD;
m >>= 1;
}
return ans;
}
int work(int n,int a,int b,int d)
{
return (C(n,a) * ksm(C(b,d),a)) % MOD;
}
signed main()
{
inv[1] = 1;
for(int i = 2;i <= 1000005;i++) inv[i] = (MOD - 1LL * (MOD / i) * inv[MOD % i] % MOD) % MOD;
fact[0] = 1;
for(int i = 1;i <= 1000000;i++) fact[i] = 1ll * fact[i - 1] * i % MOD;
invfact[0] = 1;
for(int i = 1;i <= 1000000;i++) invfact[i] = 1ll * invfact[i - 1] * inv[i] % MOD;
int n,a,b,d;
while(cin >> n >> a >> b >> d) cout << work(n,a,b,d) << endl;
return 0;
}