675 2 to omega of n.pl 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # Date: 27 June 2019
  4. # https://github.com/trizen
  5. # Based on the identity:
  6. # Sum_{d|n} 2^omega(d) = sigma_0(n^2)
  7. # The algorithm iterates over each number k in 2..N,
  8. # and computes sigma_0(k^2) = Prod_{p^e | k} (2*e + 1).
  9. # By keeping track of the partial products, we find sigma_0(k!^2).
  10. # Runtime: 44.576s
  11. # https://projecteuler.net/problem=675
  12. use 5.020;
  13. use strict;
  14. use warnings;
  15. use ntheory qw(:all);
  16. use experimental qw(signatures declared_refs);
  17. sub F ($N, $mod) {
  18. my @table;
  19. my $total = 0;
  20. my $partial = 1;
  21. foreach my $k (2 .. $N) {
  22. my $old = 1; # old product
  23. foreach my \@pp (factor_exp($k)) {
  24. my ($p, $e) = @pp;
  25. $old = mulmod($old, 2 * $table[$p] + 1, $mod) if defined($table[$p]);
  26. $table[$p] += $e;
  27. $partial = mulmod($partial, 2 * $table[$p] + 1, $mod);
  28. }
  29. $partial = divmod($partial, $old, $mod); # remove the old product
  30. $total += $partial;
  31. $total %= $mod;
  32. }
  33. return $total;
  34. }
  35. my $MOD = 1000000087;
  36. foreach my $n (1 .. 7) {
  37. printf("F(10^%d) = %*s (mod %s)\n", $n, length($MOD) - 1, F(10**$n, $MOD), $MOD);
  38. }
  39. __END__
  40. F(10^1) = 4821 (mod 1000000087)
  41. F(10^2) = 930751395 (mod 1000000087)
  42. F(10^3) = 822391759 (mod 1000000087)
  43. F(10^4) = 979435692 (mod 1000000087)
  44. F(10^5) = 476618093 (mod 1000000087)
  45. F(10^6) = 420600586 (mod 1000000087)