0134 素数对连接
* * * *
拉格朗日计划
* * * *
素数对连接

考虑两个连续的素数,例如$p_1=19$和$p_2=23$。可以验证,1219是最小的、以$p_1$结尾并且能被$p_2$整除的数。

事实上,除了3和5这对连续素数外,对于任意一对连续素数$p_2>p_1$,都存在一系列以$p_1$结尾并且能被$p_2$整除的数,记$S(p_1)$为其中最小的数,例如$S(19)=1219$。

对5到$10^6$之间的所有$p_1$,求$S(p_1)$之和。

本题难度:



解答

令k为$p_1$的位数,并记$m=10^k$,需要找到最小的、满足 $$n\equiv 0 \pmod{p_2}, \quad n\equiv p_1 \pmod m.$$ 由中国剩余定理可知上式存在形如$n=xp_1p_2$的解,那么最小的n显然就是$xp_1p_2$模$p_2m$的余数。 注意到若把$xp_1p_2$写成 $$xp_1p_2=am+p_1,$$ 的形式,那么a需要能被$p_1$整除,从而上式可以进一步简化为 $$xp_2-ym=1,$$ 其中$y=a/p_1$,这是一个标准的线性丢番图方程,有解的前提是$\gcd(p_2,m)=1$,此时逆用辗转相除法即可求出x,结果是$18613426663617118$。

target=1000000

d=[0]*target

n=2

while n < target:
    for i in range(n+n,target,n):
        d[i]=d[i]+1
    n=n+1
    while n < target and d[n]>0:
        n=n+1

primeList=[k for k in range(5,target) if d[k]==0]+[1000003]
n=len(primeList)

#return d,x,y where d=gcd(a,b); ax+by=d with x,y being one of the two pairs satisfying |x|<=y/d,|y|<=x/d
def bezout(a,b,xa=1,ya=0,xb=0,yb=1):
    r=a%b
    q=a//b
    if r==0:
        return b,xb,yb
    else:
        return bezout(b,r,xb,yb,xa-q*xb,ya-q*yb)

s=0
for i in range(n-1):
    p,q=primeList[i],primeList[i+1]
    m=10**len(str(p))
    x=bezout(q,m)[1]
    s+=(x*p*q)%(q*m)

print s