• CodeForces 1288C


    CodeForces 1288C

    组合数简单应用

    一般来说组合数简单应用难点在于怎么想到去构造组合数公式,一般在计数题中可能出现,计数题可能是组合数、计数DP。这题的难点就在于构造组合数公式

    (m)(a_i), (m)(b_i)

    (a_i leq b_i (1leq ileq n))

    考虑这样的 (2m) 非下降序列:(a_1,a_2,...a_m,b_m,b_{m-1},...b_1) 即:(a_1leq a_2leq a_3...b_mleq b_{m-1}leq b_1) 可知这样是能够满足所有条件。。

    那么就是要从 (n) 个数中选择 (2m) 个数满足非下降的条件,通过观察发现,只要你任取 (2m) 个数拍个序,必然满足非下降的条件,而且没有重复的情况。

    这可以抽象成多重集组合数的组合数模型:

    (ans = C_{n + r -1}^{n - 1} = C_{n + r -1} ^{r})

    (r = 2m)

    #include <bits/stdc++.h> 
    #define SZ(X) ((int)(X).size())
    #define ALL(X) (X).begin(), (X).end()
    #define rep(I, N) for (int I = 1; I <= (N); ++I)
    #define repp(I, N) for (int I = 0; I < (N); ++I)
    #define FOR(I, A, B) for (int I = (A); I <= (B); ++I)
    #define FORR(I, A, B) for (int I = (A); I >= (B); I--)
    #define SORT_UNIQUE(c) (sort(c.begin(),c.end()), c.resize(distance(c.begin(),unique(c.begin(),c.end()))))
    #define GET_POS(c,x) (lower_bound(c.begin(),c.end(),x)-c.begin())
    #define MP make_pair
    #define PB push_back
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MS1(X) memset((X), -1, sizeof((X)))
    #define LEN(X) strlen(X)
    #define F first
    #define S second
    using namespace std;
    const int N = 2e5 + 5;
    const double eps = 1e-7;
    const int mod = 1e9 + 7;
    typedef long long ll;
    typedef unsigned long long ULL;
    typedef long double LD;
    typedef pair<int,int> PII;
    typedef vector<int> VI;
    ll pow(ll a, ll b, ll m)
    {
        ll ans = 1;
        a %= m;
        while (b)
        {
            if (b & 1)
                ans = (ans % m) * (a % m) % m;
            b /= 2;
            a = (a % m) * (a % m) % m;
        }
        ans %= m;
        return ans;
    }
    ll inv(ll x, ll p) //x关于p的逆元,p为素数
    {
        return pow(x, p - 2, p);
    }
    ll C(ll n, ll m, ll p) //组合数C(n, m) % p
    {
        if (m > n)
            return 0;
        ll up = 1, down = 1; //分子分母;
        for (int i = n - m + 1; i <= n; i++)
            up = up * i % p;
        for (int i = 1; i <= m; i++)
            down = down * i % p;
        return up * inv(down, p) % p;
    }
    ll Lucas(ll n, ll m, ll p)
    {
        if (m == 0)
            return 1;
        return C(n % p, m % p, p) * Lucas(n / p, m / p, p) % p;
    }
    int main() {
        ll n, m;
        cin >> n >> m;
        cout << Lucas(n + 2 * m - 1, 2 * m, mod) << endl;
        return 0;
    }
    
    
  • 相关阅读:
    World file文件格式
    HTML5 基础
    Spring Framework---概况
    Tomcat(1)
    警言妙句
    嵌入式系统总是要用户对变量或寄存器进行位操作。给定一个整型变量a,写两段代码,第一个设置a的bit 3,第二个清除a 的bit 3。在以上两个操作中,要保持其它位不变。
    关键字volatile有什么含意?并给出三个不同的例子。
    关键字const有什么含意?
    关于指针数组、数组指针、指针函数、函数指针等的问题
    实现两个int变量的值的交换,要求不使用临时变量。
  • 原文地址:https://www.cnblogs.com/strategist-614/p/12608279.html
Copyright © 2020-2023  润新知