存个组合数板子

存个组合数板子

预处理阶乘求组合数

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 const ll mod=1e9+7;
 5 const ll maxn=1e6+7;
 6 ll pr[maxn];
 7 void init()//预处理一下阶乘
 8 {
 9   pr[0]=1;
10   for(int i=1;i<=maxn;i++)
11     {
12         pr[i]=pr[i-1]*i%mod;
13     }
14 }
15 ll fpow(ll a,ll b)//快速幂
16 {
17     a%=mod;
18     ll ans=1;
19     while(b)
20     {
21         if(b&1) ans=ans*a%mod;
22         a=a*a%mod;
23         b>>=1;
24     }
25     return ans%mod;
26 }
27 ll c(ll a,ll b)//打表查询
28 {
29     if (a < b || a < 0 || b < 0) return 0;
30     return pr[a]*fpow(pr[b]*pr[a-b]%mod,mod-2)%mod;//逆元套公式
31 }
32 int main()
33 {
34     init();
35     int t;
36     scanf("%d",&t);
37     while(t--)
38     {
39         ll a,b;
40         scanf("%lld%lld",&a,&b);
41         printf("%lld\n",c(a,b));
42     }
43     return 0;
44 }

 

或者直接运算

 1 ll _C(ll n,ll m)
 2 {
 3     ll ans=1;
 4     if(m>(n+1)/2)
 5     {
 6         m=n-m;
 7     }
 8     for(ll i=1;i<=m;i++)
 9     {
10         ans=ans*(n-i+1)%mod*fpow(i,mod-2)%mod;
11     }
12     return ans;
13 }

 

求n!中s的个数

 1 ll factory(ll n,ll s)//计算N!中s的个数 
 2 {
 3     ll sum=0;
 4     int i=1;
 5     while(n)
 6     {
 7         n=n/s;
 8         sum+=n;
 9     }
10     return sum;
11 }

 

下面是暴力质因数分解求组合数

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 const ll mod=1e9+7;
 5 map <ll, ll> m;
 6 map<ll,ll>::iterator it;
 7 void fun(ll n, ll k)
 8 {
 9     for(ll i=2; i*i<=n; i++)
10     {
11         if(n%i==0)
12         {
13             while(n%i==0)
14             {
15                 m[i] += k;
16                 n/=i;
17             }
18         }
19     }
20     if(n>1)
21     {
22         m[n] += k;
23     }
24 }
25 ll fpow(ll a,ll b)
26 {
27     a%=mod;
28     ll ans=1;
29     while(b)
30     {
31         if(b&1) ans=ans*a%mod;
32         a=a*a%mod;
33         b>>=1;
34     }
35     return ans%mod;
36 }
37 ll c(ll a,ll b)
38 {
39     if (a < b || a < 0 || b < 0) return 0;
40     ll ret=1;
41     b=min(a-b,b);
42     for(ll i=0; i<b; i++) fun(a-i,1);
43     for (ll i=b; i>=1; i--) fun(i,-1);
44     for (it= m.begin(); it!= m.end(); it++)
45     {
46         if (it->second != 0)
47         {
48             ret=(ret*fpow(it->first, it->second))%mod;
49         }
50     }
51     return ret;
52 }
53 int main()
54 {
55     int t;
56     scanf("%d",&t);
57     while(t--)
58     {
59         m.clear();
60         ll a,b;
61         scanf("%lld%lld",&a,&b);
62         printf("%lld\n",c(a,b));
63     }
64     return 0;
65 }

 素数筛

int cnt=0;
    vis[0]=1;
    vis[1]=1;
    for(int i=2;i<=maxn;i++)
    {
        if(!vis[i]) prime[cnt++]=i;
        for(int j=0;j<cnt&&i*prime[j]<=maxn;j++)
        {
            vis[i*prime[j]]=1;
            if(i%prime[j]==0) break;
        }
    }

 

posted @ 2020-03-15 19:37  L·S·D  阅读(284)  评论(0编辑  收藏  举报