Codeforces 300 C Beautiful Numbers (Locas)

思路:首先注意到對於長度爲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比較大的時候。

具體可以看這篇:http://blog.csdn.net/acdreamers/article/details/8037918

這裏還有一個優化 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[n]*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;
}


發佈了113 篇原創文章 · 獲贊 2 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章