【POJ3696】The Luckiest Number
题意:求出最小的x,使得由x个8组成的数可以被L整除。
$\overline{888\cdots 88}$(x个8)$=\overline{999\cdots 99}$(x个9)$\times 8/9 =8\times ({10}^x -1)/9$
$\because 8\times ({10}^x -1)/9 | L$
$\therefore 8\times ({10}^x -1) | 9L$
$\therefore {10}^x -1 | 9L/d (d=gcd(8,L))$
$\therefore {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;
}