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;
}