组合数模板

2017-08-10 19:35:32

整理者:pprp

用于计算C(m,n) % p

代码如下:

//lucas
#include <iostream>

using namespace std;

typedef long long ll;

//a^b%m 快速幂
int quick_power_mod(int a, int b, int m)
{
      int result = 1;
      int base = a;
      while(b > 0)
      {
            if(b&1 == 1)//如果b是奇数
            {
                  result = (result * base) % m;
            }
            base = (base * base)%m;
            b>>=1;
      }
      return result;
}

 //组合数取模 C(a,b)%p
 ll composition(ll a, ll b, int p)
 {
       if(a < b)
            return 0;
       if(a == b)
            return 1;
       if(b > a - b) b = a - b;
       
       int 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 * quick_power_mod(cb,p - 2, p)) % p;
       return ans;
 }
 
 ll lucas(ll n , ll m , ll p)
 {
       ll ans = 1;
       while(n && m && ans)
       {
             ans = (ans * composition(n%p, m%p, p))%p;
             n /= p;
             m /= p;
       }
       return ans;
 }

int main()
{
      ll m, n;
      
      while(cin >> m >> n)
      {
            cout << lucas(m,n,104729) << endl; //这里的104729是比较大的一个素数
      }
    return 0;
}
原文地址:https://www.cnblogs.com/pprp/p/7341054.html