129. 循环单位数整除性(Repunit divisibility)

只包含数字\(1\)的数被称为循环单位数,定义\(R(k)\)是长为\(k\)的循环单位数,如\(R(6)=111111\)。如果\(n\)是一个整数且\(gcd(n,10)=1\),可以验证总是存在\(k\)使得\(R(k)\)能够被\(n\)整除,记\(A(n)\)是这些\(k\)中最小的一个,则有\(A(7)=6,A(41)=5\)。易知使得\(A(n)\)第一次超过十的\(n\)\(17\),求使得\(A(n)\)第一次超过一百万的\(n\)

分析:题目中说"可以验证总是存在\(k\)使得\(R(k)\)能够被\(n\)整除",我们首先来看看这个判断为什么是正确的,在分析的过程中我们也可以得到解题的一些关键线索。

对于\(R_1,R_2\cdots,R_i,\cdots R_j,\cdots R_n\),假设其都不整除\(n\),则这些循环单位数模\(n\)的结果必然都落在\([1,n-1]\),然而共有\(n\)个循环单位数,则根据抽屉原理,必有\(i,j\)满足\(1\le i\le j\le n\)使得其模\(n\)的结果相同,即:

$$ R_j\equiv R_i\pmod{n}\Rightarrow R_j-R_i\equiv0\pmod{n} $$

\((R_j-R_i)\)即为一个前\((j-i)\)位数字都为一而后\(i\)位数字都为零的数,即

$$ (R_j-R_i)=R_{j-i}*10^i \Rightarrow R_{j-i}*10^i\equiv0\pmod{n} $$

\(gcd(10,n)=1\),则有\(R_{j-i}\equiv0\pmod{n}\),即一个位数在\([1,n]\)间的循环单位数可以整除\(n\),和我们的假设矛盾,所以在\(R_1\)\(R_n\)间总存一个循环单位数可以整除\(n\)。同时易知满足题目条件的\(A(n)\le n\)。因此要使得\(A(n)>10^6\),则\(n\)也必须大于\(10^6\),我们只需要从一百万向上搜索即可。

根据循环单位数的定义易知\(R_{k} =\frac{10^{k} -1}{9}\),如果其整除\(n\),则有:

$$ R_{k} =\frac{10^{k} -1}{9} \ \equiv 0\ (\bmod n) \Longrightarrow 10^{k} \equiv 1\ (\bmod 9n) $$

根据右式我们要求满足条件的最小的正整数\(k\),而这正是阶数的定义,我们可以使用\(sympy\)中相关的数论函数来求解。同时根据之前的推理,我们只需要从一百万向上搜寻即可,找到的第一个使得\(k\)大于一百万的\(n\)即为题目所求。此外因为\(gcd(n,10)=1\),则\(n\)必是一个奇数同时不整除五,这样可以进一步减少搜索空间。代码如下:

# time cost = 642 µs ± 2.22 µs

from sympy.ntheory import n_order

def main(N=10**6):
    n = N + 1
    while True:
        if n % 5 != 0 and n_order(10,9*n)>N:
            return n
        else:
            n = n + 2