您的位置:首页 > 其它

Codeforces 300 C Beautiful Numbers (Locas)

2013-04-27 20:03 411 查看
思路:首先注意到对于长度为N的数字,他各个位数相加最多不会超过b*n,那么就可以枚举小于等于b*n中由a和b组成的good数gnum,设a*x+b*y=gnum,x和y为所求n位数中a的个数和b的个数,并且x+y=n这样,就可以解得x=(m-b*n)/(a-b).只要有正整数解,就说明存在n位数good数字使得他的各个位数之和等于gnum,也就是说由x个a核y个b组成的数字都是excellent数,于是每次ans=(ans+C(n,x)%mod)%mod。gnum可以用深搜枚举,到这里都还会,之后就是和高数轮的同学讨论了,因为C(n,m)%mod涉及到Locas。

对于Locas求的是C(n,m)%p,p是素数,且n,m比较大的时候。

具体可以看这篇:/article/2371877.html

这里还有一个优化 a/b(mod p)=a%p/(b%p)=a*b^(p-2)(mod p),这样n!/((n-m)!*(m!))%mod=(n!)%mod*(((m-n)!%mod*(m!)%mod)^(mod-2))。在上面的博客中也有写

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <ctime>
using namespace std;
#define LL long long
const int maxn=1000001;
const int mod=1000000007;
LL a,b,n,x,y;
LL sum=0;
LL p[maxn];
LL quickpow(LL a,LL b)
{
LL res=1;
while(b>0)
{
if(b&1)
res=(res*a)%mod;
b>>=1;
a=(a*a)%mod;
}
return res;
}
LL C(LL n,LL m)
{
if(m>n) return 0;
return (p
*quickpow((p[n-m]*p[m])%mod,mod-2))%mod;
}
LL Locas(LL n,LL m)
{
if(m==0) return 1;
return (C(n%mod,m%mod)*Locas(n/mod,m/mod))%mod;
}
void dfs(int num)
{
if(num>b*n) return;
if(num)
{
x=num-b*n;
if(x%(a-b)==0)
{
x/=(a-b);
sum=(sum+Locas(n,x))%mod;
}
}
dfs(num*10+a);
dfs(num*10+b);
}
int main()
{
cin>>a>>b>>n;
p[0]=p[1]=1;
for(LL i=2; i<=n; i++)
p[i]=(p[i-1]*i)%mod;
sum=0;
dfs(0);
cout<<sum<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: