1. 程式人生 > >Codeforces 300C Beautiful Numbers 【組合數】+【逆元】

Codeforces 300C Beautiful Numbers 【組合數】+【逆元】

get 導出 fine 一個數 con 是不是 mat fin lan

<題目鏈接>

題目大意:

給出a和b,如果一個數每一位都是a或b,那麽我們稱這個數為good,在good的基礎上,如果這個數的每一位之和也是good,那麽這個數是excellent。求長度為n的excellent數的個數mod(1e9+7)。

解題分析:

我們可以枚舉a的個數m,所以b的個數為(n-m),然後判斷這種情況是否可行,即,是否滿足a*m+b*(n-m)為good number ,如果滿足的話,則答案加上C(n,m)。因為n很大,並且在計算組合數的過程中,需要除以很大的數,所以需要求逆元,因為本題模數為1e9+7,為質數,所以可以用費馬小定理求逆元。

#include<cstdio>
#include
<cstring> #include<algorithm> #include<cmath> #define LL long long using namespace std; const LL MOD=1e9+7; const LL MAXN=1e6+10; LL a,b; LL n; LL fact[MAXN];//存i的階乘 bool Sum_ok(LL x){ while(x){ //判斷每一位是否只由a或b組成 LL res=x%10; if(res!=a&&res!=b) return
false; x=x/10; } return true; } LL pow(LL m,LL n){ if(n==0) return 1; LL ans=1; while(n>0){ if(n&1) ans=ans*m%MOD; m=m*m%MOD; n=n/2; } return ans; } int main(){ scanf("%d %d %d",&a,&b,&n); fact[0]=1; for(LL i=1;i<=n;i++) fact[i]=fact[i-1
]*i%MOD;//將fact數組初始化將階乘的值存進數組,不要忘了取余 LL ans=0; for(LL i=0;i<=n;i++){ //枚舉a的個數 if(is_gnum(a*i+b*(n-i))){ //判斷枚舉出的數是不是good number LL t1=pow(fact[i],MOD-2)%MOD; //費馬小定理求逆元,註意求逆元的格式,fact[i]、fact[n-i]均為除數 LL t2=pow(fact[n-i],MOD-2)%MOD; ans += fact[n]*t1%MOD*t2%MOD;//利用上面講解中推導出的公式計算出答案,利用組合數公式,n!/(m!*(n-m)!) } } printf("%lld\n",ans%MOD); return 0; }

2018-10-09

Codeforces 300C Beautiful Numbers 【組合數】+【逆元】