数论---求组合数

快速幂:数论-----快速幂-CSDN博客

快速幂求逆元:数论----快速幂求逆元-CSDN博客

筛质数:筛质数----CSDN博客

求组合数I    //10万组 a,b<=2000,需要取mod  //递推    O(n*n)
  b        a*(a-1)*...*(a-b+1)        a!            
C    =  --------------------------- = ------------
  a         1*2*3*...*b                   b!(a-b)!
  
  b      b          b-1
C   =C      + C                (递推公式)
  a     a-1        a-1

#include
using namespace std;
const int N=2010,mod=1e9+7;
int c[N][N];
void init(){
	for(int i=0;i>n;
	while(n--){
		int a,b;
		cin>>a>>b;
		cout<

求组合数II    1万组(可以十万组)    a,b<=100000 ,需要取mod       // 预处理    (nlogn)
  b        a*(a-1)*...*(a-b+1)         a!
C    =------------------------------= ------------
  a         1*2*3*...*b                    b!(a-b)!
  
fact[i]=i! mod 1e9+7;    //fact[i] 表示 i 的阶乘
infact[i]=(i!)^(-1) mod 1e9+7;    //infact[i] i 的阶乘的逆元    //快速幂求
   a
C   = fact[a] * infact[b-a] *infact[b]
   b

#include
using namespace std;
typedef long long ll;
const int N=100010,mod=1e9+7;
int fact[N],infact[N];
int qmi(int a,int k,int p){
	int res=1;
	while(k){
		if(k&1)res=(ll)res*a%p;
		a=(ll)a*a%p;
		k>>=1;
	}
	return res;
}
int main(){
	fact[0]=infact[0]=1;
	for(int i=1;i>n;
	while(n--){
		int a,b;
		cin>>a>>b;
		cout<<(ll)fact[a]*infact[b]%mod*infact[a-b]%mod<

求组合数III    20组    a,b<=1e18 需要取mod       // 卢卡斯定理lucas    (p*log n * log p)
   b        b mod p       b/p
C     =C               * C         (mod p)
   a        a mod p       a/p
  

#include
using namespace std;
typedef long long ll;
const int N=100010,mod=1e9+7;
int p;
int qmi(int a,int k){
	int res=1;
	while(k){
		if(k&1)res=(ll)res*a%p;
		a=(ll)a*a%p;
		k>>=1;
	}
	return res;
}
int C(ll a,ll b){
	int res=1;
	for(int i=1,j=a;i<=b;i++,j--){
		res=(ll)res*j%p;
		res=(ll)res*qmi(i,p-2)%p;
	}
	return res;
}
int lucas(int a,int b){
	if(a>n;
	while(n--){
		ll a,b;
		cin>>a>>b>>p;
		cout<

求组合数IIII        a,b<=5000  不需要取mod

      // 算出组合数
   b      a*(a-1)*...*(a-b+1)           a!            
C    =----------------------------  =  ------------        
   a      1*2*3*...*b                     b!(a-b)!
 1. 分解质因数    //筛1~5000以内的质数 求每个质数的次数
 2. 高精度        //所有的质因子的乘积

#include
using namespace std;
typedef long long ll;
const int N=5010;
bool st[N];
int primes[N],cnt;
int sum[N];

void get_primes(int n)
{
    for (int i = 2; i <= n; i ++ )
    {
        if (!st[i]) primes[cnt ++ ] = i;	//不是质数,就加到数表里
        for (int j = 0; primes[j] <= n / i; j ++ )	//从小到大枚举所有质数
        {
            st[primes[j] * i] = true;	//筛掉
            if (i % primes[j] == 0) break;	//primes[j]一定是i的最小质因子
        }
    }
}
int get(int n,int p){
	int res=0;
	while(n){
		res+=n/p;
		n/=p;
	}
	return res;
}
vector mul(vector a, int b)       // 高精度乘低精度模板
{
    vector c;
    int t = 0;
    for (int i = 0; i < a.size(); i ++ )
    {
        t += a[i] * b;
        c.push_back(t % 10);
        t /= 10;
    }

    while (t)
    {
        c.push_back(t % 10);
        t /= 10;
    }

    return c;
}

int main(){

	int a,b;
	cin>>a>>b;
	get_primes(a);
	
	for(int i=0;i res;
	res.push_back(1);
	for (int i = 0; i < cnt; i ++ )     // 用高精度乘法将所有质因子相乘
    	for (int j = 0; j < sum[i]; j ++ )
        	res = mul(res, primes[i]);
    for(int i=res.size()-1;i>=0;i--)cout<

你可能感兴趣的:(算法,c++,组合数,数论)