这题的关键还是如何求等比数列之和,之前使用的二分求和...这里用数论的知识直接解决...
对于(a/b)%c这类运算不能等价于(a%c / b%c)...但是可以等价为(a*b')%c...其中b'为b的逆元..
而(a*b')%c这类运算可以拆解为(a%c * b%c)..
那么关键就是求c的逆元了.. 值得留意的是10000007是一个质数...
根据费马小定理对于任意的质数p有任意的正整数a满足a^(p-1)%p==1
如果A是a的逆元..那么A*a % p==1...而又a*a^(p-2)%p==a^(p-1)%p==1 所以a的逆元A=a^(p-2)%p
剩下的就简单了..
Program:
#include<iostream> #include<stdio.h> #include<string.h> #include<set> #include<algorithm> #include<cmath> #define oo 1000000007 #define ll long long #define pi acos(-1.0) #define MAXN 505 using namespace std; char s[100004]; ll len; ll POW(ll a,ll k) { ll x,ans=1; x=a; while (k) { if (k%2) ans=(ans*x)%oo; x=(x*x)%oo; k/=2; } return ans; } ll T(ll n,ll t) { ll ans,x=POW(POW(2,len)-1,oo-2); ans=(t*POW(POW(2,len),n)-t)%oo; return (ans*x)%oo; } int main() { int k,i; ll ans,x,l; while (~scanf("%s",s)) { scanf("%d",&k); len=strlen(s); ans=0; x=1; for (i=0;i<len;i++) { if (s[i]=='0' || s[i]=='5') ans=(ans+x)%oo; // 不要每次都做..加起来 x=(x*2)%oo; } ans=T(k,ans); // 只做一次 printf("%I64d\n",ans); } return 0; }