专栏文章
题解:SP28304 ADATEAMS - Ada and Teams
SP28304题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mioozxpy
- 此快照首次捕获于
- 2025/12/02 22:47 3 个月前
- 此快照最后确认于
- 2025/12/02 22:47 3 个月前
这是一个排列组合问题。
事先声明
思路
而且,我们还要在每一所学校的 名学生中选择 名参赛,所以每一所学校的选择方案数为 。因为我们总共有 所学校参赛,所以后面是 。
由思路到实现
首先,我们处理 (,下同)对于 的乘法逆元,以及 的阶乘及其乘法逆元。
在以后对于计算 与 组合的处理中,我们可以直接返回 。其中, 代表阶乘数组, 代表阶乘逆元数组。
最后,我们统计一下时间复杂度:初始化 ,单次查询 ,时间复杂度在可接受范围内。
在以后对于计算 与 组合的处理中,我们可以直接返回 。其中, 代表阶乘数组, 代表阶乘逆元数组。
最后,我们统计一下时间复杂度:初始化 ,单次查询 ,时间复杂度在可接受范围内。
代码
#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;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...