AT5341 [ABC156D] Bouquet

原题链接

  • 题意:Akari 有 \(n\) 种不同的花,她可以选择其中一种或多种花做成花束。但是 Akari 不喜欢花的种数恰好为 \(a\)\(b\) 的花束。求出她组合花的合法方案总数,对 \(10^9+7\) 取模。
    \(2 \le n \le 10^9\)
    \(1 \le a < b \le \min(n,2 \times 10^5)\)
  • 题解:思路很简单就能想到,很显然是 \(2^n - C(n, a) - C(n, b)\) 但是主要是想记录一下求组合数,如果 \(n-m <= 1e5\) 还是很容易求的,是 \(\frac{n!}{m!n-m!}\),即 \(\frac{\prod^{n}_{i =1}i }{m!}\) 复杂度也是 \(O(n)\)
  • 代码:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <vector>

using namespace std;
typedef long long ll;
const ll NN = 1e7 + 99;
const ll N = 2e5 + 99;
const ll mod = 1e9 + 7;

const ll maxn = 1e7;
ll fac[N];
void init() {
    fac[0] = 1;
    fac[1] = 1;
    for (ll i = 1; i < N; i ++) {
        fac[i] = fac[i-1] * i%mod;
    }
}
ll q_pow(ll a, ll k) {
    ll ret = 1;
    ll x = a;
    while (k) {
        if (k & 1) (ret *= x)%=mod;
        k >>= 1;
        (x *= x)%=mod;
    }
    return ret;
}
ll inv(ll a) {
    return (q_pow(a, mod-2) % mod + mod) % mod;
}
ll C(ll n ,ll m) {
    ll x = 1;
    for (ll i = n-m + 1;i <= n; i++ ) {
        (x *= i) %= mod;
    }
    return x*inv(fac[m]) % mod;
}
void solve() {
    ll n, a, b;
    cin >> n >> a >> b;
    cout << ((((((q_pow(2, n) - C(n, a) ) %mod + mod)%mod - C(n,b))%mod + mod )%mod-1)%mod +mod)%mod<< endl;
}
signed main() {
    ios::sync_with_stdio(0);
    init();
    ll t = 1;
    while (t--) solve();
    return 0;
}
posted @ 2021-03-31 16:43  u_yan  阅读(103)  评论(0编辑  收藏  举报