partial_sums_of_lcm_count_function.sf 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #!/usr/bin/ruby
  2. # Let f(n) be the number of couples (x,y) with x and y positive integers, x ≤ y and the least common multiple of x and y equal to n.
  3. # Let a(n) = A007875(n), with a(1) = 1, for n > 1 (due to Vladeta Jovovic, Jan 25 2002):
  4. # a(n) = (1/2)*Sum_{d|n} abs(mu(d))
  5. # = 2^(omega(n)-1)
  6. # = usigma_0(n)/2
  7. # This gives us f(n) as:
  8. # f(n) = Sum_{d|n} a(d)
  9. # This script implements a sub-linear formula for computing partial sums of f(n):
  10. # S(n) = Sum_{k=1..n} f(k)
  11. # = Sum_{k=1..n} Sum_{d|k} a(d)
  12. # = Sum_{k=1..n} a(k) * floor(n/k)
  13. # See also:
  14. # https://oeis.org/A007875
  15. # https://oeis.org/A064608
  16. # https://oeis.org/A182082
  17. # Problem from:
  18. # https://projecteuler.net/problem=379
  19. # Several values for S(10^n):
  20. # S(10^1) = 29
  21. # S(10^2) = 647
  22. # S(10^3) = 11751
  23. # S(10^4) = 186991
  24. # S(10^5) = 2725630
  25. # S(10^6) = 37429395
  26. # S(10^7) = 492143953
  27. # S(10^8) = 6261116500
  28. # S(10^9) = 77619512018
  29. # S(10^10) = 942394656385
  30. # S(10^11) = 11247100884096
  31. func usigma0_partial_sum (n) { # O(sqrt(n)) complexity
  32. var total = 0
  33. var s = n.isqrt
  34. var u = idiv(n, s+1)
  35. var prev = squarefree_count(n)
  36. for k in (1..s) {
  37. var curr = squarefree_count(idiv(n, k+1))
  38. total += (prev - curr)*k
  39. prev = curr
  40. }
  41. u.each_squarefree {|k|
  42. total += idiv(n, k)
  43. }
  44. return total
  45. }
  46. func S(n) {
  47. dirichlet_sum(n,
  48. {|k| (k == 1) ? 1 : usigma0(k)/2 }, # a(n)
  49. { 1 },
  50. {|k| (usigma0_partial_sum(k)-1)/2 }, # partial sums of a(n)
  51. { _ }
  52. )
  53. }
  54. for k in (1..5) {
  55. say "S(10^#{k}) = #{S(10**k)}"
  56. }