zoukankan      html  css  js  c++  java
  • 组合数

    递推公式

    求解C(n, m)%p

    费马小定理的转换

    线性求inv和fac

    
    #include<bits/stdc++.h>
    #define ll long long
    #define asd cout<<"!"<<endl
    using namespace std;
    const ll maxn=1e6+10;//memory:20068KB!!
    const ll p=1e9+7;
    ll fac[maxn];
    ll inv[maxn];
    int a[maxn];
    void fac_init()
    {
        fac[0]=fac[1]=1;//both 0 1 initiate
        for (int i=1;i<maxn;i++) fac[i]=(fac[i-1]*(i%p))%p;
        inv[0]=inv[1]=1;
    	for(int i=2;i<maxn;i++) inv[i]=(p-p/i)*inv[p%i]%p;    
    	for(int i=2;i<maxn;i++) inv[i]=inv[i]*inv[i-1]%p;//little trick
    }
    ll C(int i,int j)
    {
    	return fac[i]*inv[i-j]%p*inv[j]%p;
    }
    int main()
    {	
        fac_init();
    	int n;
    	cin>>n;
    	for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    	a[0]=1000,a[n+1]=1;
    	ll l=0;
    	ll ans=1;
    	for (int i=1;i<=n+1;i++) if (a[i])
    	{
    		if (a[l]<a[i]) break;
    		ans=ans*C(a[l]-a[i]+i-l-1,i-l-1);//little trick?
    		ans%=p;
    		l=i;//little trick
    	}
    	cout<<ans;	
    }
    

    拓展欧几里得

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const ll maxn=2000+10;
    const ll MAX=200+10;
    const ll p=1e9+7;
    ll fac[maxn];//n!
    ll inv[maxn];//(n!)^(-1)
    ll c[maxn][maxn];
    void Exgcd(ll a, ll b, ll &x, ll &y) {
        if (!b) x = 1, y = 0;
        else Exgcd(b, a % b, y, x), y -= a / b * x;
    }
    void fac_init()
    {
    	fac[0]=1;
    	for (ll i=1;i<=MAX;i++) fac[i]=(fac[i-1]*(i%p))%p;
    }
    ll get_inv(ll k)
    {
    	ll x,y;
    	Exgcd(k,p,x,y);
    	x=(x%p+p)%p;
    	return x;
    }
    int main()
    {
    	fac_init();
    	ll T;
    	cin>>T;
    	while (T--)
    	{
    		ll n,m;
    		cin>>n>>m;		
    		for (ll i=1;i<=MAX;i++)
    		for (ll j=1;j<=i;j++)
    		{
    			c[i][j]=(fac[i]*get_inv((fac[i-j]*fac[j])%p))%p;
    		}
    		printf("%lld
    ",c[n][m]);	
    	}	
    }
    
    

    费马小定理和卢卡斯定理//???
    搬运:https://xienaoban.github.io/posts/36480

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll p=10007;
    ll pow_mod(ll a, ll b, const int &pr)
    {
    	ll ans = 1;
    	while (b) {
    		if (b & 1) ans = ans * a % pr;
    		b >>= 1;
    		a = a * a % pr;
    	}
    	return ans;
    }
    ll C_small(ll n, ll m, const int &pr)
    {
    	ll ans = 1;
    	for (int i = 1; i <= m; i++)
    	{
    		ll a = (n - m + i) % pr;
    		ll b = i % pr;
    		ans = ans * (a * pow_mod(b, pr - 2, pr) % pr) % pr; //Fermat Theory
    	}
    	return ans;
    }
    ll C(ll n, ll m, const int &pr) // Lucas's theorem
    {
    	if (m == 0 || m == n) return 1;
    	return C_small(n % pr, m % pr, pr) * C(n / pr, m / pr, pr) % pr;
    }
    int main()
    {
    	ll n,m;
    	cin>>n>>m;
    	cout<<C_small(n,m,p)<<endl;
    	cout<<C(n,m,p)<<endl;
    }
    
  • 相关阅读:
    8. Andr&#233;nalin ★ Serial
    1 Acid burn ★ Nag,Name/Serial,Serial
    【CPP】字符串和格式化输入输出
    什么是生成器
    【python密码学编程】8.使用换位加密法加密
    【python密码学编程】6.凯撒加密法
    【CPP】数据和C
    【python密码学编程】7.暴力破解凯撒加密法
    HDOJ 4515 小Q系列故事——世界上最遥远的距离
    POJ1131 Octal Fractions
  • 原文地址:https://www.cnblogs.com/reshuffle/p/12252449.html
Copyright © 2011-2022 走看看