prog.sf 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. #!/usr/bin/ruby
  2. # Sum of the remainders when n^2 is divided by squares less than n.
  3. # https://oeis.org/A067459
  4. # a(n) = Sum_{k=1..n-1} (n^2 mod k^2)
  5. # This program implements a sub-linear formula for computing a(n).
  6. # Some optimizations may be possible...
  7. # Sub-linear formula motivated by A340457, where:
  8. # A340457 = Squares in A067459: 0, 0, 1, 4356, 164025, ...
  9. func faulhaber_range(a,b,k) {
  10. faulhaber(b, k) - faulhaber(a-1, k)
  11. }
  12. func f(n) { # Sum_{k=1..n} k^2 * floor(n^2 / k^2)
  13. return 1 if (n == 1)
  14. var total = 0
  15. var u = 0
  16. var k = 1
  17. var s = n*n
  18. func next_k(k, x) {
  19. var r = n/(x-1)
  20. bsearch_min(k, n, {|v|
  21. n/idiv(s, v*v) <=> r
  22. })
  23. }
  24. while (k <= n) {
  25. var r = idiv(s, k*k)
  26. if (u == r) {
  27. var w = next_k(k, r)
  28. total += faulhaber_range(k, w-1, 2)*r
  29. k = w
  30. }
  31. else {
  32. total += (k*k * r)
  33. ++k
  34. }
  35. if (k >= n) {
  36. k = n if (k > n)
  37. total += faulhaber_range(k, n, 2)*(n - k + 1)
  38. break
  39. }
  40. u = r
  41. }
  42. return total
  43. }
  44. func a(n) {
  45. n**3 - f(n)
  46. }
  47. func test_a_1(n) {
  48. n**3 - sum(1..n, {|k|
  49. k**2 * floor(n**2 / k**2)
  50. })
  51. }
  52. func test_a_2(n) {
  53. sum(1..^n, {|k|
  54. n**2 % k**2
  55. })
  56. }
  57. say 30.of(a)
  58. say a(10**5) #=> 129205044499930
  59. say a(10**6) #=> 129207957923604833