http://codeforces.com/contest/300/problem/C
題意:一個n位的數只包含a,b兩個數字並且每一位元字的和也只包含這兩個數字,求這樣的數有多少?
做法:枚舉a出現的次數為x,則b為n-x。如果sum = ax+b(n-x)合法,則這種情況的數目為C(n,x).
C(n,x) = n! / ( (n-x)! * x! ) (mod p) = n! * inv( (n-x)! * x!) {inv(a)為a的乘法逆元}。
求乘法逆元的方法(a存在mod p的乘法逆元若且唯若a與p互質):
=>
法一:擴充歐幾裡德定理
=> =>
法二:歐拉定理(結合快速冪)
根據歐拉定理,如果a與m互質,則有 => (φ(m)為m的歐拉函數,即少於或等於m的數中與m互質的數的數目)
特殊的,當m為素數時,少於或等於m的數中與m互質的數的數目為m-1,即
法二
1 /* 2 *Author: Zhaofa Fang 3 *Created time: 2013-04-25-18.24 4 *Language: C++ 5 */ 6 #include <cstdio> 7 #include <cstdlib> 8 #include <sstream> 9 #include <iostream>10 #include <cmath>11 #include <cstring>12 #include <algorithm>13 #include <string>14 #include <utility>15 #include <vector>16 #include <queue>17 #include <map>18 #include <set>19 using namespace std;20 21 typedef long long ll;22 #define DEBUG(x) cout<< #x << ':' << x << endl23 #define FOR(i,s,t) for(int i = (s);i <= (t);i++)24 #define FORD(i,s,t) for(int i = (s);i >= (t);i--)25 #define REP(i,n) for(int i=0;i<n;i++)26 #define REPD(i,n) for(int i=n-1;i>=0;i--)27 #define PII pair<int,int>28 #define PB push_back29 #define MP make_pair30 #define ft first31 #define sd second32 #define lowbit(x) (x&(-x))33 #define INF (1<<30)34 35 const ll mod = 1000000007;36 37 ll fac[1000111];38 39 40 void init(int n){41 fac[0] = 1;42 FOR(i,1,n){43 fac[i] = fac[i-1]*i%mod;44 }45 }46 ll pow_mod(ll a,ll m,ll n){47 ll tmp = 1;48 a%=n;49 while(m){50 if(m&1)tmp = tmp*a%n;51 a = a*a%n;52 m>>=1;53 }54 return tmp;55 }56 57 bool check(int a,int b,int sum){58 while(sum>0){59 int tmp = sum%10;60 if(tmp!=a&&tmp!=b)return false;61 sum/=10;62 }63 return true;64 }65 int main(){66 //freopen("in","r",stdin);67 //freopen("out","w",stdout);68 int a,b,n;69 scanf("%d%d%d",&a,&b,&n);70 ll ans = 0;71 init(n);72 REP(i,n+1){73 int x = i;74 int y = n - i;75 int sum = a*x + b*y;76 if(check(a,b,sum)){77 ll tmp = fac[n]*pow_mod(fac[y]*fac[x],mod-2,mod)%mod;78 ans = (ans + tmp)%mod;79 }80 }81 cout<<ans<<endl;82 return 0;83 }
附:維基的資料