#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 ...