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;
    }
    
  • 相关阅读:
    27. Remove Element
    26. Remove Duplicates from Sorted Array
    643. Maximum Average Subarray I
    674. Longest Continuous Increasing Subsequence
    1. Two Sum
    217. Contains Duplicate
    448. Find All Numbers Disappeared in an Array
    566. Reshape the Matrix
    628. Maximum Product of Three Numbers
    UVa 1349 Optimal Bus Route Design (最佳完美匹配)
  • 原文地址:https://www.cnblogs.com/reshuffle/p/12252449.html
Copyright © 2011-2022 走看看