zoukankan      html  css  js  c++  java
  • 组合数

    转自acwing

    1.询问次数大

    // c[a][b] 表示从a个苹果中选b个的方案数
    for (int i = 0; i < N; i ++ )
        for (int j = 0; j <= i; j ++ )
            if (!j) c[i][j] = 1;
            else c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;

    2

    首先预处理出所有阶乘取模的余数fact[N],以及所有阶乘取模的逆元infact[N]
    如果取模的数是质数,可以用费马小定理求逆元
    int qmi(int a, int k, int p)    // 快速幂模板
    {
        int res = 1;
        while (k)
        {
            if (k & 1) res = (LL)res * a % p;
            a = (LL)a * a % p;
            k >>= 1;
        }
        return res;
    }
    
    // 预处理阶乘的余数和阶乘逆元的余数
    fact[0] = infact[0] = 1;
    for (int i = 1; i < N; i ++ )
    {
        fact[i] = (LL)fact[i - 1] * i % mod;
        infact[i] = (LL)infact[i - 1] * qmi(i, mod - 2, mod) % mod;
    }
    

    3数据极大(10^18)

    若p是质数,则对于任意整数 1 <= m <= n,有:
        C(n, m) = C(n % p, m % p) * C(n / p, m / p) (mod p)
    
    int qmi(int a, int k)       // 快速幂模板
    {
        int res = 1;
        while (k)
        {
            if (k & 1) res = (LL)res * a % p;
            a = (LL)a * a % p;
            k >>= 1;
        }
        return res;
    }
    
    
    int C(int a, int b)     // 通过定理求组合数C(a, b)
    {
        int res = 1;
        for (int i = 1, j = a; i <= b; i ++, j -- )
        {
            res = (LL)res * j % p;
            res = (LL)res * qmi(i, p - 2) % p;
        }
        return res;
    }
    
    
    int lucas(LL a, LL b)
    {
        if (a < p && b < p) return C(a, b);
        return (LL)C(a % p, b % p) * lucas(a / p, b / p) % p;
    }
  • 相关阅读:
    7
    go http请求库HttpRequest
    Golang设计模式
    深挖 go 之 for-range 排坑指南
    go在并发情况下使用map
    Redis知识点总结
    go 条件与循环结构
    数据分析的数据源
    go 生产者消费者模型与发布订阅模型
    go 文件与目录操作
  • 原文地址:https://www.cnblogs.com/cyq123/p/12979748.html
Copyright © 2011-2022 走看看