【POJ3696】The Luckiest Number

题意:求出最小的x,使得由x个8组成的数可以被L整除。

$overline{888cdots 88}$(x个8)$=overline{999cdots 99}$(x个9)$ imes 8/9 =8 imes ({10}^x -1)/9$

$ecause 8 imes ({10}^x -1)/9 | L$

$ herefore 8 imes ({10}^x -1) | 9L$

$ herefore {10}^x -1 | 9L/d (d=gcd(8,L))$

$ herefore {10}^x equiv 1(mod 9L/d )$

有一个定理:

若正整数$a,n$互质,则满足$a^x equiv 1 (mod n )$的最小正整数是$varphi(n)$的约数。

对应上式,则要求出$varphi(9L/d)$和它的约数,逐一判断即可。

还有一个地方,%运算十分慢,为提高效率,要把乘方化成乘法,把乘法化成加法,就可以用减法代替%运算。

超时快速幂:

ll poww(ll a,int b,ll mod)
{
    ll fac=a%mod,ans=1ll%mod;
    while(b)
    {
        if (b&1) ans=ans*fac%mod;
        fac=fac*fac%mod;
        b>>=1;
    }
    return ans;
}

 

优化:

 

void add(ll &a,const ll &b,const ll &mod)//const常量、传址加速 
{
 a+=b;if (a>mod) a-=mod;//经过以前的模运算后,a<2*mod,可以直接用减法
}
ll mul(ll a,ll b,const ll &mod)
{
 ll sum=0ll;
 while(b)
 {
  if (b&1) add(sum,a,mod);//乘法化log(b)次加法
  add(a,a,mod);
  b>>=1;
 }
 return sum;
}
ll poww(ll a,ll b,ll mod)
{
 ll ans=1ll;a%=mod;
 while(b)
 {
  if (b&1) ans=mul(ans,a,mod);//乘方化乘法
  a=mul(a,a,mod);
  b>>=1;
 }
 return ans;
}
原文地址:https://www.cnblogs.com/xzs123456/p/10415436.html