Codeforces Round #191 (Div. 2) C magic five

来源:互联网 发布:视频转换器 for mac 编辑:程序博客网 时间:2024/05/16 07:30

题目大意:给定一个字符串 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 进行计算并将结果相加,即可得到最后答案。


模p乘法逆元对于整数a、p,如果存在整数b,满足ab mod p =1,则说,b是a的模p乘法逆元。

如果gcd(a,p)=d,则存在m,n,使得d = ma + np,称这种关系为a、b组合整数d,m,n称为组合系数。当d=1时,有 ma + nb = 1 ,此时可以看出m是a模p的乘法逆元,n是p模a的乘法逆元。 故可用扩展欧几里得求乘法逆元。但算出来的m,n可能为负数,最后要把它转化为正数。

定理:a存在模p的乘法逆元的充要条件是gcd(a,p) = 1

证明:首先证明充分性如果gcd(a,p) = 1,根据欧拉定理,aφ(p) ≡ 1 mod p,因此显然aφ(p)-1 mod p是a的模p乘法逆元。再证明必要性假设存在a模p的乘法逆元为bab ≡ 1 mod p则ab = kp +1    ,所以1 = ab - kp因为gcd(a,p) = d所以d | 1所以d只能为1
代码如下:
#include<cstdio>#include<cmath>#include<cstring>#include<cstdlib>#define  N 100005typedef  long long ll;const int  mod=1e9+7;ll k;char str[N];void extgcd(ll a, ll b, ll &x, ll &y){         if(b==0)         {                  x=1;                  y=0;                  return;         }         extgcd(b,a%b,x,y);         ll t=x;x=y;y=t-a/b*y;}ll  Pow(ll a,ll b){        ll ret=1;        while(b)        {                 if(b&1) ret=ret*a%mod;                 a=a*a%mod; b>>=1;        }        return ret;}int  main(){         while(~scanf("%s %d",str,&k))         {                ll len=strlen(str);                ll u=( Pow( 2, len * k ) - 1 + mod ) % mod;                ll q=( Pow( 2, len ) - 1 + mod ) % mod;                ll x,y,ans=0;                extgcd(q,mod,x,y);                while(x<0)  x+=mod;                for(int i=0;i<len;i++)                {                         if(str[i]=='0' || str[i]=='5')                         {                               ans = (ans + (Pow(2,i) % mod * u % mod * x %mod) ) %mod;                         }                }                printf("%I64d\n",ans);         }         return 0;}


原创粉丝点击