1 条题解
-
1
每个人至少要分到一个礼物不好求,那么可以求"有个人没有分到礼物" 相当于多了个礼物,人少了个,因此此时的组合数为 然后容斥原理应用:首先选个空手的人,有种选择方式; 每一项
* C(n, i):选择哪个人空手。容斥的符号规则:当为偶数时(空手人数为偶),方案数加;当为奇数时(空手人数为奇),方案数减; 代码如下:
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; typedef long long LL; const int N = 1e5 + 10; const LL mod = 1e9 + 7; LL n, m; LL a[N]; LL fact[N], infact[N]; LL dp[N]; LL qmi(LL a, LL b, LL m){ LL res = 1; while(b){ if(b & 1) res = (LL) res * a % m; a = (LL) a * a % m; b >>= 1; } return res; } void init(){ fact[0] = 1; infact[0] = 1; for(LL i = 1; i < N; i ++) { fact[i] = (LL)fact[i - 1] * i % mod; infact[i] = qmi(fact[i], mod - 2, mod) % mod; } } LL C(LL a, LL b) { if(a < b) return 0; return fact[a] * infact[b] % mod * infact[a - b] % mod; } int main(){ init(); cin >> n >> m; for(int i = 1; i <= m; i++){ cin >> a[i]; } for(int i = 0; i < n; i++){ //枚举空的人数 dp[i] = 1; for(LL j = 1; j <= m; j++){ //种类 dp[i] = (LL)(dp[i] % mod) * (LL)C(a[j] + n - i - 1, n - i - 1) % mod; } } //容斥 LL res = 0; for(LL i = 0; i < n; i++){ LL temp = dp[i] * C(n, i) % mod; if(i % 2 != 0) res -= (LL)(temp % mod + mod) % mod; else res += (LL)(temp % mod) % mod; } cout << (res % mod + mod) % mod << endl; return 0; } //146 150 72
信息
- ID
- 263
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 7
- 标签
- (无)
- 递交数
- 24
- 已通过
- 7
- 上传者