• 快速求排列组合 lucas定理


    对于C(n, m) mod p。这里的n,m,p(p为素数)都很大的情况。

    就不能再用C(n, m) = C(n - 1,m) + C(n - 1, m - 1)的公式递推了。

     一般lucas定理的p不能大,在1e6以内,一下代码应该可以吧

    typedef long long LL;
    using namespace std;
    
    LL exp_mod(LL a, LL b, LL p) {
        LL res = 1;
        while(b != 0) {
            if(b&1) res = (res * a) % p;
            a = (a*a) % p;
            b >>= 1;
        }
        return res;
    }
    
    LL Comb(LL a, LL b, LL p) {
        if(a < b)   return 0;
        if(a == b)  return 1;
        if(b > a - b)   b = a - b;
    
        LL ans = 1, ca = 1, cb = 1;
        for(LL i = 0; i < b; ++i) {
            ca = (ca * (a - i))%p;
            cb = (cb * (b - i))%p;
        }
        ans = (ca*exp_mod(cb, p - 2, p)) % p;
        return ans;
    }
    
    LL Lucas(int n, int m, int p) {
         LL ans = 1;
    
         while(n&&m&&ans) {
            ans = (ans*Comb(n%p, m%p, p)) % p;
            n /= p;
            m /= p;
         }
         return ans;
    }

      上面是在线的算法,如果数字小还可以用以下写法

    void pre()  //i表示n,j表示m
    {
        C[1][0]=C[1][1]=1;
        for(int i=2;i<=1000;i++)
        {
            C[i][0]=1;
            for(int j=1;j<=1000;j++)
              C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
        }
        return;
    }
  • 相关阅读:
    各种小例子
    作业 5/20
    课程总结
    构建之法 读书笔记一
    Android实现本地音频播放(可拖动条)
    自我介绍
    上周总结
    《梦断代码》读书笔记三
    《梦断代码》读书笔记二
    《梦断代码》读书笔记一
  • 原文地址:https://www.cnblogs.com/stepping/p/7228378.html
Copyright © 2020-2023  润新知