求組合數的C 實現

2022-09-18 00:09:19 字數 2088 閱讀 8346

#include 

<

iostream

>

using

namespace

std;

intcom(

intn,

intr)

}returns;}

intmain()

return0;

}

上面的**只適合較小的n,經測試,當n=33 時,對於所有小於等於 n 的 m均能計算出值。n>33時,僅對於較小的m適用。

在網上找了找,學會了計算組合數的新方法

下面的**則利用了素數唯一分解定理

n=p1^e1*p2^e2*...*pr^er 其中pi為素數因子,ei是正整數。

n是素數當且僅當 r=1 且 e1=1

組合數計算演算法流程:1,素數打表  2,冪整數拆分  3,快速冪模

藍色字為引用:

有乙個小函式,求n!中含數x的幾次方

int getx(int n,int x)//計算n!中質因子2的出現次數

int getx(int n,int x)//非遞迴寫法

return ans;

}演算法解釋:

60/5=12;12/5=2;所以可以肯定60!中含有5^14

第一次的60/5 我們找到了5^1倍數的所有數,

第二次12/5 相當於(60/5)/2==60/5^2,集計算60中含有5^2倍數的個數

…………以此類推

注意:由於n/(x^i-1)計算已經包含了n/x^i的n/(x^i-1)部分,所以n/x^i僅算n/x^i

個x,而非(n/x^i)*i個x,

2.拆分後對分式進行降冪運算

x1[i]-=(x2[i]+x3[i]) 可以證明x1[i]>=0

證明:由於c(n,m)結果必然為整數,即n!%((n-m)!*m!)==0

所以n!為(n-m)!*m!的整數倍,即pi^x1i%(pi^x2i*pi^x3i)==0

即pi^(x1[i]-x2[i]-x3[i])為整數

x1[i]-x2[i]-x3[i]>=0

證畢

#include

<

iostream

>

#include

<

cstring

>

#include

<

cmath

>

#define

set(a) memset(a,0,sizeof(a))

#define

m 150000

#define

n 1000001

#define

mod 20110413

/*c(n,m)=n! / ((n-m!)*m!)

n!=2^x1*3^x2*5^x3***pi^xi

*/int

p[m];

intx1[m];

//n!

intx2[m];

//(n-m)!

intx3[m];

//m!

intpn;

//numbers of the prime number

using

namespace

std;

intgetprime()}if

(flag==1

) p[k++]

=i;}returnk;}

intgetx(

intn,

intp)

returnx;}

intdiv(

intn,

intx)

returni;}

__int64 b_pow(

int*

arr,

intn)

res=

(res

*d)

%mod;}}

return

res;

}__int64 c(

intn,

intm)

intmain()

return0;

}

組合數學 求組合數

對於求組合數,要根據所給資料範圍來選擇合適的演算法 這道題中所給的資料範圍適合用打表的方法直接暴力求解 先用4e6的複雜度預處理出所有的情況,再用1e4的複雜度完成詢問即可 include using namespace std const int n 2010 const int mod 1e9 ...

C 求組合數 再取模

c n,m n n m m c 在處理大數除法的時候好像會出現問題,所以用除法有時候會因為精度不夠沒法得到正確答案.需要把除法變成乘法.知識儲備 逆元 快速冪 逆元 若a x m 1 我們稱x是a的逆元,x寫做a 1 相當於整除中的倒數 那假設我們要求a b m的值,當b特別大時我們無法得到正確答案...

吉首 組合數 求組合數因子個數

時間限制 1 sec 記憶體限制 128 mb 求組合數c n,m 以及c n,m 因子個數。n和m,其中0 m n 50,以eof結束。該組合數結果。3 2 4 23 2 6 4先利用楊輝三角求出組合數,然後就是求出因子數了 求因子數 素數分解的唯一性,乙個數可以被分解成若干素數相乘 p1 x1 ...