C. Magic Five

C. Magic Five

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 524288/262144K (Java/Other)
Total Submission(s) : 12   Accepted Submission(s) : 3
Problem Description

There is a long plate s containing n digits. Iahub wants to delete some digits (possibly none, but he is not allowed to delete all the digits) to form his "magic number" on the plate, a number that is divisible by 5. Note that, the resulting number may contain leading zeros.

Now Iahub wants to count the number of ways he can obtain magic number, modulo 1000000007 (109+7). Two ways are different, if the set of deleted positions in s differs.

Look at the input part of the statement, s is given in a special form.

 

 

Input

In the first line you're given a string a (1≤|a|≤105), containing digits only. In the second line you're given an integer k (1≤k≤109). The plate s is formed by concatenating k copies of a together. That is n=|a|k.

 

 

Output

Print a single integer the required number of ways modulo 1000000007 (109+7).

 

 

Sample Input
1256
1
13990
2
 

 

Sample Output
4
528
 
/**
Codeforces Round #191 (Div. 2) C magic five
 
题目大意:给定一个字符串 s,长度 len 最长是100000,接着输入一个整数 k,k 最大是10的9次方,
求 k 个 s 连接在一起得到一个串,设为str,从str中删除一些数(也可以不删,但不能全部删除),
使得得到的数能够整除5,求共有多少种删除方式,注意:被删除的数的位置不同,算做不同的删除方式。
 
解题思路:我们知道如果一个数能够整除5,那它的个位数一定是 0 或者 5 。
因此我们需要在串 s 中找到每个 0 或者 5 的位置,假设第一个找到的位置为 i ,
易证明,以此位置的0(或者5)为尾数共有 2 的 i 次方种删除方式,
进而可得由 k 个 s 组成的串 str 中有 2 的 i 次幂 + 2 的 (i+len*1)次幂 + …… + 2 的 [ i + len *(k-1)] 次幂,
易发现这是一个首项为2的 i 次幂,公比为 2 的 len 次幂的等比数列求和,我们用快速幂和乘法逆元解决。
所以对串 s 中每个0 或者5 进行计算并将结果相加,即可得到最后答案。
 
 
/**
Codeforces Round #191 (Div. 2) C magic five
 
题目大意:给定一个字符串 s,长度 len 最长是100000,接着输入一个整数 k,k 最大是10的9次方,
求 k 个 s 连接在一起得到一个串,设为str,从str中删除一些数(也可以不删,但不能全部删除),
使得得到的数能够整除5,求共有多少种删除方式,注意:被删除的数的位置不同,算做不同的删除方式。
 
解题思路:我们知道如果一个数能够整除5,那它的个位数一定是 0 或者 5 。
因此我们需要在串 s 中找到每个 0 或者 5 的位置,假设第一个找到的位置为 i ,
易证明,以此位置的0(或者5)为尾数共有 2 的 i 次方种删除方式,
进而可得由 k 个 s 组成的串 str 中有 2 的 i 次幂 + 2 的 (i+len*1)次幂 + …… + 2 的 [ i + len *(k-1)] 次幂,
易发现这是一个首项为2的 i 次幂,公比为 2 的 len 次幂的等比数列求和,我们用快速幂和乘法逆元解决。
所以对串 s 中每个0 或者5 进行计算并将结果相加,即可得到最后答案。
 
 
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
typedef __int64 ll;
const ll N = 1e5+5;
char s[N];
const ll mod = 1e9+7;
ll pw[N];
ll extgcd(ll a,ll b,ll &x,ll &y)
{
    if(b==0) {
        x = 1, y = 0; return a;
    }
    ll d = extgcd(b,a%b,x,y);
    ll t = x;
    x = y;
    y = t-a/b*y;
    return d;
}
ll inverse(ll t)
{
    ll x, y;
    ll d = extgcd(t,mod,x,y);
    return (x%mod+mod)%mod;
}
ll Pow(ll a,ll b)
{
    ll p = 1;
    while(b>0){
        if(b&1){
            p = p*a%mod;
        }
        a = a*a%mod;
        b>>=1;
    }
    return p;
}
int main()
{
    ll k, p = 1;
    pw[0] = 1;
    for(ll i = 1; i < N; i++){
        p = p*2%mod;
        pw[i] = p;
    }
    while(scanf("%s",s)!=EOF)
    {
        scanf("%I64d",&k);
        ll len = strlen(s);
        ll ans = 0;
        ll t = Pow(2,len);
        for(ll i = 0; s[i]!='\0'; i++){
            if(s[i]=='0'||s[i]=='5')
            ans = (ans+pw[i]*(Pow(t,k)-1)%mod*inverse(t-1))%mod;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

 

posted on 2015-10-21 20:27  hnust_accqx  阅读(407)  评论(0编辑  收藏  举报

导航