partial_sums_of_2_to_the_bigomega_of_n.sf 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #!/usr/bin/ruby
  2. # Daniel "Trizen" Șuteu
  3. # Date: 22 May 2020
  4. # Edit: 11 July 2020
  5. # https://github.com/trizen
  6. # Fast formulas for computing: Sum_{k=1..n} 2^bigomega(k).
  7. # OEIS:
  8. # https://oeis.org/A069205 -- a(n) = Sum_{k=1..n} 2^bigomega(k).
  9. # Let:
  10. # S(n) = Sum_{k=1..n} 2^bigomega(k)
  11. # Is it possible to compute S(n) in sublinear time? The answer is "yes".
  12. # Formula #1:
  13. #
  14. # S(n) = 1 + Sum_{k=1..floor(log_2(n))} 2^k * pi_k(n)
  15. #
  16. # where pi_k(n) is the number of k-almost primes <= n.
  17. # Formula #2:
  18. #
  19. # S(n) = Sum_{2-powerful k <= n} 2^(bigomega(k) - 2*omega(k)) * D(floor(n/k))
  20. #
  21. # where D(n) = Sum_{k=1..n} floor(n/k), computed in O(sqrt(n)) steps as:
  22. #
  23. # D(n) = 2*Sum_{k=1..floor(sqrt(n))} floor(n/k) - floor(sqrt(n))^2
  24. # See also:
  25. # https://projecteuler.net/problem=708
  26. func S(n) {
  27. 1 + sum(1..n.ilog2, {|k|
  28. 2**k * k.almost_primepi(n)
  29. })
  30. }
  31. func T(n) {
  32. 2.powerful(n).sum {|k|
  33. 2**(bigomega(k) - 2*omega(k)) * dirichlet_hyperbola(
  34. floor(n/k), { 1 }, { 1 }, { _ }, { _ }
  35. )
  36. }
  37. }
  38. assert_eq(
  39. 1..100->map{|k| 2**bigomega(k) }.accumulate,
  40. 1..100->map(S),
  41. )
  42. assert_eq(
  43. 1..100->map(S),
  44. 1..100->map(T),
  45. )
  46. for k in (1..6) {
  47. var a = S(10**k)
  48. var b = T(10**k)
  49. assert_eq(a,b)
  50. say "S(10^#{k}) = #{a}"
  51. }
  52. __END__
  53. S(10^1) = 33
  54. S(10^2) = 811
  55. S(10^3) = 15301
  56. S(10^4) = 260615
  57. S(10^5) = 3942969
  58. S(10^6) = 55282297
  59. S(10^7) = 746263855
  60. S(10^8) = 9613563919
  61. S(10^9) = 120954854741