wayne于2014年3月转载projectEuler 454问题 :
设对于给定的 L L L ,等式 1 X + 1 Y = 1 N , ( 0 < X < Y ⩽ L ) \frac1X + \frac1Y = \frac1N, (0 \lt X \lt Y \leqslant L) X 1 + Y 1 = N 1 , ( 0 < X < Y ⩽ L ) 成立总共有 f ( L ) f(L) f ( L ) 种情况 .
举几个简单的例子, 有 f ( 6 ) = 1 , f ( 12 ) = 3 , f ( 1000 ) = 1069 f(6) =1, f(12)=3, f(1000)=1069 f ( 6 ) = 1 , f ( 1 2 ) = 3 , f ( 1 0 0 0 ) = 1 0 6 9 , 求f ( 1 0 12 ) f(10^{12}) f ( 1 0 1 2 ) .
参考链接
公式推导
wayne指出:
x + y ( x , y ) ∣ ( x , y ) \frac{x+y}{(x,y)}\mid (x,y) ( x , y ) x + y ∣ ( x , y )
不过,在此基础上,可以导出这种一般性的解表达: x = k m ( m + n ) , y = k n ( m + n ) , ( m , n ) = 1 , m < n x=km(m+n) ,y=kn(m+n), (m,n)=1, m\lt n x = k m ( m + n ) , y = k n ( m + n ) , ( m , n ) = 1 , m < n , 即L = k n ( m + n ) L=kn(m+n) L = k n ( m + n )
但要计算出f ( 1 0 12 ) f(10^{12}) f ( 1 0 1 2 ) ,还需要进一步的挖掘,优化.
LwinsG给出进一步公式推导过程 :
直接计算$ \sum {n=1}^{\sqrt{L}} \sum_{m=1,(n,m)=1}^{n-1} [\frac{L}{n(n+m)}] 只需要 只需要 只 需 要 O(L)$的时间,我认为这是可以承受的。不过我们也可试着优化一下:
∑ n = 1 L ∑ m = 1 , ( n , m ) = 1 n − 1 [ L n ( n + m ) ] = ∑ n = 1 L ∑ s = n + 1 , ( n , s ) = 1 2 n − 1 [ L n s ] = ∑ n = 1 L ∑ s = n + 1 2 n − 1 [ L n s ] [ 1 ( n , s ) ] = ∑ n = 1 L ∑ s = n + 1 2 n − 1 [ L n s ] ∑ d ∣ ( n , s ) μ ( d ) = ∑ n = 1 L ∑ d ∣ n ∑ n < s ≤ 2 n − 1 , d ∣ s [ L n s ] μ ( d ) = ∑ n = 1 L ∑ d ∣ n μ ( d ) ∑ n d < s ′ ≤ 2 n − 1 d [ L n d s ′ ] = ∑ n = 1 L ∑ d ∣ n μ ( d ) ( ψ ( [ L n d ] , 2 n − 1 d ) − ψ ( [ L n d ] , n d ) ) \sum_{n=1}^{\sqrt{L}} \sum_{ m=1,(n,m)=1 }^{n-1} [ \frac{L}{n(n+m)} ]
=\sum_{n=1}^{\sqrt{L}} \sum_{s=n+1 , (n,s)=1 }^{2n-1} \left[ \frac{L}{ns} \right]
=\sum_{n=1}^{\sqrt{L}} \sum_{s=n+1}^{2n-1} \left[ \frac{L}{ns} \right] \left[ \frac{1}{(n,s)} \right]
=\sum_{n=1}^{\sqrt{L}} \sum_{s=n+1}^{2n-1} \left[ \frac{L}{ns} \right] \sum_{d | (n,s)} \mu(d)
=\sum_{n=1}^{\sqrt{L}} \sum_{d | n} \sum_{ n < s \leq 2n-1, d | s } \left[ \frac{L}{ns} \right] \mu(d)
=\sum_{n=1}^{\sqrt{L}} \sum_{d | n} \mu(d) \sum_{\frac{n}{d} < s^{\prime} \leq \frac{2n-1}{d}} \left[ \frac{L}{nds^{\prime}} \right]
=\sum_{n=1}^{\sqrt{L}} \sum_{d | n} \mu(d) \left( \psi\left( \left[ \frac{L}{nd} \right],\frac{2n-1}{d}\right) - \psi\left(\left[ \frac{L}{nd} \right],\frac{n}{d}\right) \right) ∑ n = 1 L ∑ m = 1 , ( n , m ) = 1 n − 1 [ n ( n + m ) L ] = ∑ n = 1 L ∑ s = n + 1 , ( n , s ) = 1 2 n − 1 [ n s L ] = ∑ n = 1 L ∑ s = n + 1 2 n − 1 [ n s L ] [ ( n , s ) 1 ] = ∑ n = 1 L ∑ s = n + 1 2 n − 1 [ n s L ] ∑ d ∣ ( n , s ) μ ( d ) = ∑ n = 1 L ∑ d ∣ n ∑ n < s ≤ 2 n − 1 , d ∣ s [ n s L ] μ ( d ) = ∑ n = 1 L ∑ d ∣ n μ ( d ) ∑ d n < s ′ ≤ d 2 n − 1 [ n d s ′ L ] = ∑ n = 1 L ∑ d ∣ n μ ( d ) ( ψ ( [ n d L ] , d 2 n − 1 ) − ψ ( [ n d L ] , d n ) )
计算ψ ( x , y ) = ∑ n = 1 y [ x n ] \psi(x,y) = \sum_{n=1}^{y} \left[ \frac{x}{n} \right] ψ ( x , y ) = ∑ n = 1 y [ n x ] 显然是O ( x ) O(\sqrt{x}) O ( x ) 的。
于是使用该公式可以做到在O ( L 3 / 4 ) O(L^{3/4}) O ( L 3 / 4 ) 的复杂度内计算。
cn8888给出了这个丢番图方程的几何意义 :
倪举鹏表示 :
还有种几何关系满足这个等式:平面过一点的三射线中间射线与两边射线夹角都是60度。一条直线截这3射线为三段,这三段长度满足这个等式.
sunwukong认为 :
因为
1 x + 1 y = 1 n \frac1x+\frac1y=\frac1n x 1 + y 1 = n 1 ,0 < x < y ≤ L 0\lt x\lt y\leq L 0 < x < y ≤ L
所以 n < x < y ≤ L n\lt x\lt y\leq L n < x < y ≤ L
设 x = n + s x=n+s x = n + s ,y = n + t y=n+t y = n + t ,则1 ≤ s < t ≤ L − n 1\leq s\lt t\leq L-n 1 ≤ s < t ≤ L − n
1 n + s + 1 n + t = 1 n ⟺ n 2 = s t \frac1{n+s}+\frac1{n+t}=\frac1{n} \iff n^2=st n + s 1 + n + t 1 = n 1 ⟺ n 2 = s t
所以
n 2 = s t ≥ 1 × 2 = 2 ⇒ n ≥ 2 n^2=st\geq1\times 2=2 \Rightarrow n\geq 2 n 2 = s t ≥ 1 × 2 = 2 ⇒ n ≥ 2
s = n 2 t ≥ n 2 L − n s=\frac{n^2}t\geq \frac{n^2}{L-n} s = t n 2 ≥ L − n n 2
n 2 L − n ≤ s < n < t ≤ L − n \frac{n^2}{L-n}\leq s\lt n\lt t\leq L-n L − n n 2 ≤ s < n < t ≤ L − n
1 n = 1 x + 1 y > 1 L + 1 L = 2 L ⇒ n < L 2 \frac1{n}=\frac1x+\frac1y\gt \frac1L+\frac1L=\frac2L \Rightarrow n\lt \frac{L}{2} n 1 = x 1 + y 1 > L 1 + L 1 = L 2 ⇒ n < 2 L
所以
f ( L ) f(L) f ( L )
= ∑ n = 2 ⌊ L − 1 2 ⌋ ∑ s ≥ n 2 L − n , s ∣ n 2 n − 1 1 =\sum_{n=2}^{\lfloor \frac{L-1}{2} \rfloor} \sum_{ s\geq\frac{n^2}{L-n} , s| n^2}^{n-1} 1 = ∑ n = 2 ⌊ 2 L − 1 ⌋ ∑ s ≥ L − n n 2 , s ∣ n 2 n − 1 1
= ∑ n = 2 ⌊ L − 1 2 ⌋ ∑ t = n + 1 , t ∣ n 2 L − n 1 =\sum_{n=2}^{\lfloor \frac{L-1}{2} \rfloor} \sum_{ t=n+1, t|n^2 }^{L-n} 1 = ∑ n = 2 ⌊ 2 L − 1 ⌋ ∑ t = n + 1 , t ∣ n 2 L − n 1
= ∑ n = 2 ⌊ L − 1 2 ⌋ ( ∑ u ≥ n 2 L − n , u ∣ n 2 L − n 1 ) − 1 2 =\sum_{n=2}^{\lfloor \frac{L-1}{2} \rfloor} \frac{(\sum_{ u\geq\frac{n^2}{L-n} , u| n^2}^{L-n} 1)-1}2 = ∑ n = 2 ⌊ 2 L − 1 ⌋ 2 ( ∑ u ≥ L − n n 2 , u ∣ n 2 L − n 1 ) − 1
关键的是
给定 n n n ,L L L ,求满足
t ∣ n 2 t| n^2 t ∣ n 2 ,n < t ≤ L − n n\lt t\leq L-n n < t ≤ L − n
的t t t 的数目
这一步的复杂度与n 2 n^2 n 2 的质因数分解相同
kastin指出 :
其实就是涉及大数分解,虽然大数分解本身没有什么高效率的算法,但是这个题目只是统计解的个数,而非找到每一组解。
联想到给出不大于x x x 的素数个数π ( x ) \pi(x) π ( x ) 的算法目前最高效的算法中,并不需要找出所有小于x的素数然后统计个数(见M. DELEGLISE AND J. RIVAT.COMPUTING (x): THE MEISSEL, LEHMER, LAGARIAS,MILLER, ODLYZKO METHOD)
因而,n 2 n^2 n 2 满足一定限制要求的分解方案数,应该有相应不需要找出每种具体方案的高效算法。
开始计算
wayne试着开始计算
L = 10 ^4; phi = Sum[ Floor[
Sum[ MoebiusMu[ j] ( phi[ Floor[ L/( j i) ] ,( 2i-1) /j] -phi[ Floor[ L/( j i) ] ,i/j] ) ,{ i,1,Sqrt[ L] } ,{ j,Divisors[ i] } ]
但是他发现这份Mathematica代码计算1 0 7 10^7 1 0 7 就要40秒
Lwins_G测试后认为Mathematica计算ψ ( x , y ) \psi(x,y) ψ ( x , y ) 时所消耗的时间是平凡的,为O ( y ) O(y) O ( y ) ,这会导致复杂度退化为
∑ n = 1 L ∑ d ∣ n O ( n d ) = O ( L ) \sum\limits_{n=1}^{\sqrt{L}}\sum\limits_{d\mid n} O(\frac nd)=O(L) n = 1 ∑ L d ∣ n ∑ O ( d n ) = O ( L )
所以需要自己重新实现。
282842712474直接使用Lwins_G的公式 用phyton计算出f ( 1 0 7 ) = 30093331 , f ( 1 0 8 ) = 349446716 f(10^7)=30093331,\quad f(10^8)=349446716 f ( 1 0 7 ) = 3 0 0 9 3 3 3 1 , f ( 1 0 8 ) = 3 4 9 4 4 6 7 1 6 ,前者用时1.7秒,后者用时17秒。
f ( 1 0 9 ) = 3979600400 f(10^9)=3979600400 f ( 1 0 9 ) = 3 9 7 9 6 0 0 4 0 0 ,用时196.748994145秒... 按这个速度1 0 12 10^{12} 1 0 1 2 预计需要3天时间才能计算出来。
对应的python代码
然后他继续实现 O ( L 3 4 ) O(L^{\frac34}) O ( L 4 3 ) 复杂度的代码 , 测试运行f ( 1 0 9 ) f(10^9) f ( 1 0 9 ) 提升到24秒。
最终他实现 了O ( L ) O(\sqrt{L}) O ( L ) 复杂度的算法,这份代码 用时101秒计算出f ( 1 0 12 ) = 5435004633092 f(10^{12})=5435004633092 f ( 1 0 1 2 ) = 5 4 3 5 0 0 4 6 3 3 0 9 2 .