这题的关键还是如何求等比数列之和,之前使用的二分求和...这里用数论的知识直接解决...
对于(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;
- }