来源:牛客网
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=1,n=100,那么此时的解a1=2^1+2^2(幂1表示为从左到右第一次出现'0'的位置,幂2表示第二个出现'0'的位置)->10(1)0(2),,再如k=2,n=100,即为->100100,那么此时的解为S2=2^1+2^2+2^4+2^5,其中
a2=2^4+2^5=(2^1+2^2)*2^3=a1*q,咦,是不是看出故事了,这就是相当于一个等比数列和公式,等比q为2^3(3为n的位数),我们知道等比数列和的公式为:
嗯呢,是不是很简单,骚年,你还年轻呢, 这里的数据很大,你能这样直接算吗?有人说,我不是可以边算边模吗?哦,好像是哦,但你有没有看到,这个公式是有除数的,你能直接模吗?不能,那我们得怎么做呢?很简单,求(q-1)得乘法逆元ni,这样就直接转化成求a1*(1-q^n)*ni%mod,
ax≡1 (mod p),用拓展欧几里得求(q-1)的乘法逆元,看成a*x+p*y=1;关于什么是乘法逆元,可以去看我的另外一篇文章或者找百度。做这题还需要用到快速幂。
代码如下:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define mod 1000000007
#define MAX 100000+5
typedef long long LL;
char str[MAX];
LL sortpow(LL a,LL b) ///快速幂a^b
{
LL ans=1;
a=a%mod;
while(b)
{
if(b&1==1) ans=(ans*a)%mod;
b=b>>1;
a=(a*a)%mod;
}
return ans;
}
LL e_cal(LL a,LL b,LL &x,LL &y)
{
if(b==0)
{
x=1;y=0;
return a;
}
LL ans=e_cal(b,a%b,x,y);
LL temp=x;
x=y;
y=temp-a/b*y;
return ans;
}
LL cal(LL a,LL b,LL c) ///拓展欧几里得求逆元
{
LL x,y;
LL gcd=e_cal(a,b,x,y);
if(c%gcd!=0) return -1;
x*=c/gcd;
b/=gcd;
if(b<0) b=-b;
LL ans=x%b;
if(ans<=0) ans+=b;
return ans;
}
int main()
{
LL k,q,len,ni,Sn,an,a1;
while(~scanf("%lld",&k))
{
scanf("%s",str);
// printf("%s\n",str);
a1=0;
for(int i=0;str[i]!='\0';i++)
{
if(str[i]=='0'||str[i]=='5'){
a1=(a1+sortpow((LL)2,i))%mod;
}
}
len=strlen(str);
q=sortpow((LL)2,len);/// 等比
ni=cal(q-1,mod,1); ///求逆元
an=a1*sortpow(q,(k-1))%mod;
Sn=(an*q-a1)%mod*ni%mod;
// Sn=(a1*(sortpow(q,k)-1)%mod*ni%mod);
printf("%lld\n",Sn);
}
return 0;
}
over:
我的标签:做一个有情怀的程序员。