自带函数:
ds[n_] := Sum[DivisorSigma[1, i], {i, 1, n}]
ds@(10^5) // AbsoluteTiming
(* {0.715172,8224740835} *)
效率惨不忍睹啊
画个图比较容易看出来了:
showmegrid[n_] :=
Grid[Table[If[Divisible[i, j], j, Null], {i, n}, {j, n}], ItemSize -> All]
showmegrid[36]
以Floor[Sqrt[n]]为界,以左按照“约数*该约数出现的次数”来求和,右边的按照“若干条等差数列 ”来求和:
ds1[n_] := Module[{
a = Floor[Sqrt[n]]},
s1 = Total@Table[d Floor[n/d], {d, 1, a}];
s2 = Sum[((a + 1) + Floor[n/d])/2 (Floor[n/d] - (a + 1) + 1), {d, 1,
a}]; s = s1 + s2]
使用向量提速:
ds2[n_] := Module[{
a = Floor[Sqrt[n]]},
list1 = Table[d, {d, 1, a}];
list2 = Table[Floor[n/d], {d, 1, a}];
s = list1.list2 + 1/2 (list2 + (a + 1)).(list2 - a)]
测试结果:
test[n_] := {ds1
@n // AbsoluteTiming, ds2@n // AbsoluteTiming}
test[10^12]
(* {{13.3386, 822467033425357340138978}, {2.94121, 822467033425357340138978}} *)
速度会有些提升,可惜还是不如python:zhihu.com/question/38031089 (@bhuztez)
不知道mathematica还有什么别的优化方法吗