1. 程式人生 > >快速冪求逆元求解組合數

快速冪求逆元求解組合數

求解組合數時,如果分子或分母過大可能會爆精度,所以要邊算邊取模,乘法取模很簡單((a * b) % mod == (a % mod * b % mod) % mod。而除法沒有這種性質,所以要藉助逆元來求。在模為p的條件下,除以一個數等於乘以這個數的逆元。a * b % p = 1,  則b為a在模p下的逆元。(有個前提,p一定要為質數)

逆元可以用費馬小定理求:b = a^(p - 2);

#include <iostream>

using namespace std;

typedef long long ll;
const int mod = 1e9 + 7;

ll quick_pow(ll a, ll b)        ///快速冪求逆元
{
  ll ans = 1;
  while(b)
  {
    if(b % 2)
    {
      ans *= a;
      ans %= mod;
    }
    a *= a;
    a %= mod;
    b /= 2;
  }
  return ans;
}

ll C(int m, int n)           ///組合數公式:C(m, n) = n!/(m! * (n - m)!)
{
  if(m > n)
    return 0;
  ll ans = 1;
  for(int i = 1; i <= m; i++)
  {
    ll a, b;
    a = (n - m + i) % mod;
    b = i % mod;
    ans = ans * (a * quick_pow(b, mod - 2) % mod) % mod;
  }
  return ans;
}

int main()
{
  int m, n;
  cin >> m >> n ;
  cout << C(m, n ) << endl;
  return 0;
}

相關推薦

快速求解合數

求解組合數時,如果分子或分母過大可能會爆精度,所以要邊算邊取模,乘法取模很簡單((a * b) % mod == (a % mod * b % mod) % mod。而除法沒有這種性質,所以要藉助逆元來求。在模為p的條件下,除以一個數等於乘以這個數的逆元。a * b % p

【板子】gcd、exgcd、乘法快速快速乘、篩素數、快速合數

1.gcd int gcd(int a,int b){return b?gcd(b,a%b):a;} 2.擴充套件gcd )extend great common divisor ll exgcd(ll l,ll r,ll &x,ll &

[模板] gcd、exgcd、乘法快速快速乘、篩素數、快速合數

1.gcd int gcd(int a,int b){ return b?gcd(b,a%b):a; } 2.擴充套件gcd )extend great common divisor ll exgcd(ll l,ll r,ll &x,ll &

快速__合數

快速冪: 遞迴形式: static long pow_mod(long a, long n) { if (n == 0) { return 1; } long x = pow_mod(a, n / 2); long ans = x * x % MOD; if ((n

HDU 5793 A Boring Question (找規律 : 快速+乘法)

cnblogs and ott miss 逆元 找規律 -- for while A Boring Question Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Ot

各種求法 合數取模 comb (合數 Lucas)

組合數取模(comb) 【問題描述】 計算C(m,n)mod 9901的值 【輸入格式】 從檔案comb.in中輸入資料。 輸入的第一行包含兩個整數,m和n 【輸出格式】 輸出到檔案comb.out中。 輸出一行,一個整數 【樣例輸入】 2

取石子(快速

連結:https://www.nowcoder.com/acm/contest/113/A來源:牛客網題目描述給出四堆石子,石子數分別為a,b,c,d。規定每次只能從堆頂取走石子,問取走所有石子的方案數

合數取模(楊輝三角打表 & (擴充套件歐幾里得、費馬小定理、尤拉定理、線性求法) & Lucas)

    在acm競賽中,組合數取模的題目還是經常會見到的,所以這是有必要掌握的一個演算法。我本人就因為這個東西而被坑了很多次了= =之前的部落格也都扯過了,就不多說了,下面進入正題。 (1)楊輝三角求組合數     楊輝三角這個東西應該都不陌生,三角的兩邊始終為一,之後向

求解合數取模---拓展歐幾里德和費馬小定理求解

組合數:C(n, m) ;         組合數取模:C(n, m) % mod,mod是一個很大的數。1.公式:2.性質:(1)C(n,m)= C(n,n-m)   其中有C(n, 0) = 1;(2)C(n,m)=C(n-1,m-1)+C(n-1,m)。可以用作遞迴中的

合數

求一個數a的模p(一般為質數,否則有些數求不出逆元)的逆元。 (1) 費馬小定理: 費馬小定理是數論中的一個重要定理,其內容為: 假如p是質數,且(a,p)=1,那麼 a^(p-1) ≡1(mod p)。即:假如a是整數,p是質數,且a,p互質,那麼a的(p-1

如何快速求解合數 C(n,m) 取模 【最簡單的方法】

如何快速求解組合數 C(n,m) 取模 組合數取模,肯定要用到乘法逆元,像我這種蒟蒻,還不會。 但是我學到了一個更優秀的方法,不僅快速求解C(n,m),而且還可以mod。 這需要用到質因數拆分: 我們知道Cmn=n!(n−m)!m!Cnm=n!(n−m

poj 3070 Fibonacci(矩陣快速Fibonacci數列)

代碼 include cnblogs inf stream exp class set names 題目鏈接: http://poj.org/problem?id=3070 題意: 我們知道斐波那契數列0 1 1 2 3 5 8 13…… 數列中的第i位為第i-1位

HDU 5407 CRB and Candies(LCM +最大素因子)

blog std 歸納 get pos http and -a 思路 【題目鏈接】click here~~ 【題目大意】求LCM(Cn0,Cn1,Cn2....Cnn)%MOD 的值 【思路】來圖更直觀: 這個究竟是怎樣推出的,說實話。本人數學歸納大法沒有推出來

51Nod 1118 機器人走方格--

() uic stream pri pac ostream ios iostream %d (x/y) %mod =x*(y^(mod-2))%mod; 在算x,y的時候可以一直mod 來縮小 y^(mod-2)顯然是個快速冪 #include <iostr

各種方法總結[轉]

str com 情況 sans esp 找到 解法 () clu 各種求逆元方法總結[轉] 在MOD的情況下, (a*b/c ) %MOD 不能直接 / c 來求,需要找到一個數 inv 使得 inv * c % MOD = 1 。 這樣 (a*b / c) % M

幾種的方法

int 才有 gpo log swa class ++ 要求 1-n 一, 擴展歐幾裏得 1 void exgcd(int a,int b,int &x,int &y) 2 { 3 if(b==0) 4 { 5 x

乘法 求解及應用

情況 turn iii 直接 復雜 級別 return 這樣的 線性 乘法逆元定義 假設a,x,b為整數,b>1,且有$ax \equiv 1(\mod b)$成立 那麽a,x互為膜b的逆元 通俗一些,即兩數乘積膜p等於1,則他們互為b的逆元 ************

線性的算法

span class 介紹 floor 求逆 方法 lin spa inline 本文介紹\(O(n)\)處理\([1, n]\)在模\(P\)意義下的逆元的方法。 結論 \[inv_i \equiv -\lfloor \frac{P}{i} \rfloor * inv_{

【learning】 多項式詳解+模板

n) 意義 詳解 需要 一個 求逆 ont time 前置 概述 多項式求逆元是一個非常重要的知識點,許多多項式操作都需要用到該算法,包括多項式取模,除法,開跟,求ln,求exp,快速冪。用快速傅裏葉變換和倍增法可以在$O(n log n)$的時間復雜度下求出一個$n$次

BZOJ 3456: 城市規劃 與 算法介紹(多項式 , dp)

間接 zoj 3456 ini 不難 har 大小 #define form lock 題面 : 求有 \(n\) 個點的無向有標號連通圖個數 . \((1 \le n \le 1.3 * 10^5)\) 題解 : 首先考慮 dp ... 直接算可行的方案數 ,