HDU 3037 Saving Beans (method + Lucas separator theorem)

< Topic link >

Subject to the effect:
save no more than $ m $ single pea tree stars with $ n $ ($ n, m \ leq10 ^ 9 $) ( not necessarily all of the trees have beans stored), ask your total number of cases. The answer to modulo p (p is a prime number guaranteed).


Solving Analysis:
may be converted to n-$ $ $ identical balls into $ m sets, the number of balls and some may be set to 0 equivalent problem.
Obviously, this method can be solved by a separator, the answer is $ C (n + m-1 , m-1) $
is the number of topics can be converted to seek solutions: $ C (n + m- 1,0) + C (n + m-1,1) + C (n + m-1,2) + ...... + C (n + m-1, m-1) $

Equation using a combination of the number of $ C (n, k) = C (n-1, k) + C (n-1, k-1) $. The above equation is converted to $ C (n + m, m)% p $.

It is now required $ C (n + m, m)% p $.

Because a large n, m, and p is a prime number, can be directly solved by Lucas theorem.

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int N = 1e5+100;
ll fac[N],mod;

inline void init(){
    fac[0]=1;
    for(int i=1;i<=mod;i++)
        fac[i]=fac[i-1]*i%mod;
}

ll ksm(ll a,ll b){
    ll ans=1;a%=mod;
    while(b){
        if(b&1)ans=ans*a%mod;
        a=a*a%mod;
        b>>=1;
    }return ans;
}
ll C(ll n,ll m){      
    if(m>n)return 0;
    return fac[n]*(ksm(fac[m]*fac[n-m]%mod,mod-2))%mod;   //费马小定理求逆元
}
ll Lucas(ll n,ll m){
    if(m==0)return 1;
    return C(n%mod,m%mod)*Lucas(n/mod,m/mod)%mod;
}
int main(){
    ll n,m,T;cin>>T;
    while(T--){
        cin>>n>>m>>mod;
        init();
        cout<<Lucas(n+m,m)<<endl;
    }    
}

 



Guess you like

Origin www.cnblogs.com/00isok/p/10932254.html