It’s universally acknowledged that there’re innumerable trees in the campus of HUST.
Note that when we transfer the string to a integer, we ignore the leading zeros. For example, the string “00055” will be seen as 55. And also pay attention that two ways are considered different if the removed trees are different. The result can be very large, so printing the answer (mod 1000000007) is enough. And additionally, Xiao Ming can't cut down all trees.
输入描述:
输出描述:
A single integer, the number of ways to remove trees mod 1000000007.
输入
1 100
输出
6
说明
Initially, the sequence is ‘100’. There are 6 ways: 100 1_0 10_ _00 __0 _0_
输入
3 125390
输出
149796
题意:输入一个看k,表示 下面字符串要重复多少次;下面一行为字符串,在重复k次的字符串中去掉一些字符,使得能整除5,去掉字符不同,则为不同的方法,最后结果可能会很大,mod 1000000007
思路:能乘除5的一定是0或者5结尾,所以 只要当前字符是0或者5的话,那么就可以把它之前的 字符去掉任意改个;若当前字符是i的话,前面有i个字符,那么 从前面字符 选出 0 去掉,从中选出 1 去掉,从中选出 2去掉......从中选出 i个去掉
求逆元的解释: 点击打开链接
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define Max 100010
#define ll long long
const long long mod = 1000000007;
char str[Max];
ll p_pow(ll a,ll b) // a^b
{
ll res = 1;
while(b)
{
if(b&1) res = res*a%mod;
b>>=1;
a = a*a % mod;
}
return res;
}
int main()
{
ll i,j,k;
while(~scanf("%lld",&k))
{
scanf("%s",str);
ll l = strlen(str);
ll q = p_pow(2,l);
ll fz = p_pow(q,k);
fz = ((1-fz)%mod + mod)%mod;
ll fm = ((1-q)%mod+mod)%mod;
ll temp = fz*(p_pow(fm,mod-2))%mod; // 费马小定理求逆元;
ll res = 0;
for(i = 0;i<l;i++)
{
if(str[i] == '5'||str[i]=='0')
{
//res += p_pow(2,i)*temp%mod; // 我不知道这样写是不是溢出了,但是他就是不对了;
res +=p_pow(2,i); // 把 temp 提出来,先让括号内的相加;
}
}
res = (res%mod)*temp%mod;
printf("%lld\n",res);
}
return 0;
}