CF327C Magic Five

Solution

考虑只有一个 \(a\) 串的情况:

当第 \(i\) 位是 \(0\)\(5\) 时,我们可以选择删或不删前 \(0\) ~ \(i-1\) 位(当然 \(i\) 后面的必须删),设 \(tmp_i\) 为有 \(i\) 个串的情况,那么共有 \(tmp_1=2^0\cdot(a_0==5||0)+2^1\cdot(a_1==5||0)+\cdots+2^i\cdot(a_i==5||0)\cdots\)

然后考虑如果多了一个串:

那么 \(tmp_1\) 要乘上 \(2^{len_a}\)\(2^n\)\(tmp_2=tmp1\cdot2^n\)

共有 \(k\) 个串,所以 \(tmp_k=tmp_1\cdot (2^n)^{k-1}\)\(ans=tmp_1+tmp_2+\cdots+tmp_k\) ,由等比数列求和公式可化为: \(ans=tmp_1\cdot\frac{2^{nk}-1}{2^n-1}\) 。( \(\frac 1{2^n-1}\) 用费马小定理求一下逆元,不然会超时滴 )

注意:因为可能出现前导零,所以前导零也要算。

代码

#include<bits/stdc++.h>
#define ll long long

using namespace std;
const int mod=1e9+7;
char a[100005];
ll k,tmp;

ll fpow(ll a,ll b){
    ll res=1;
    while(b){
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}

int main(){
    scanf("%s%lld",a,&k);
    ll n=strlen(a);
    for(int i=0;i<n;i++)
        if(a[i]=='5'||a[i]=='0')
            tmp=(tmp+fpow(2,i))%mod;
    printf("%lld\n",tmp*(fpow(2,n*k)-1)%mod*(fpow(fpow(2,n)-1,mod-2))%mod);
    return 0;
}
posted @ 2020-09-26 09:14  jasony_sam  阅读(133)  评论(0编辑  收藏  举报