Codeforces327C Magic Five[组合数学]

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ControlBear/article/details/75115525

C. Magic Five
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

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 = |ak.

Output

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

Examples
input
1256
1
output
4
input
13990
2
output
528
input
555
2
output
63
Note

In the first case, there are four possible ways to make a number that is divisible by 5: 5, 15, 25 and 125.

In the second case, remember to concatenate the copies of a. The actual plate is 1399013990.

In the third case, except deleting all digits, any choice will do. Therefore there are 26 - 1 = 63 possible ways to delete digits.


题意:

给出一个长度不超过1e5的数字串,询问连着k(1<=k<=1e9)个这样的串,任意删除数字,能构成多少个5的倍数(会有重复,并且允许有多个前导0)。


题解:

首先,要构成5的倍数,那就代表末位一定为0或者为5,那么只要找到该串的5跟0的位置,就可以计算。

先不管后面会重复k个的问题,单纯的看串中的5跟0。

从第一位开始往后找5跟0,只要找到,我们可以知道只要他是最末位就可以,那么我们可以假定后面都去掉了,我们设这个数字的当前位为x,那么他前面的数字去掉的方案数是  。

因为  我们就可以直接求出当前位作为末位的所有方案数。

但是重复k个的时候,当前位在下一个重复串的位置是x+len(len是该串的长度),根据这个,我们可以得到该串的每个5跟0的一个等比数列,然后根据等比数列求和 公比q就是

但是公式中有除法的存在,而且题目的结果很大,要求取模,所以除法的取模注意求乘法逆元。


#pragma comment(linker, "/STACK:102400000,102400000")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<vector>
using namespace std;
typedef long long ll;
const int N=1e5+5;
const int mod=1e9+7;
char sen[N];
int k;
ll Pow(ll n,ll m)
{
    ll ans=1;
    while (m)
    {
        if (m&1)
            ans=ans*n%mod;
        n=n*n%mod;
        m>>=1;
    }
    return ans;
}
int main()
{
	while (~scanf("%s",sen))
    {
        scanf("%d",&k);
        int len=strlen(sen);
        ll q=Pow(2,len);
        ll ans=0;
        ll now=1;
        for (int i=0 ; i<len ; ++i)
        {
            if (sen[i]=='0' || sen[i]=='5')
                ans=(ans+now*((Pow(q,k)-1+mod)%mod)%mod*Pow((q-1+mod)%mod,mod-2)%mod)%mod;

            now=now*2%mod;
        }
        printf("%I64d\n",ans);
    }
	return 0;
}


阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页