650 Divisors of Binomial Product -- v2.pl 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # Date: 15 January 2019
  4. # https://github.com/trizen
  5. # Formula for computing the sum of divisors of the product of binomials.
  6. # Using the identities:
  7. # Product_{k=0..n} binomial(n, k) = Product_{k=1..n} k^(2*k - n - 1)
  8. # = hyperfactorial(n)/superfactorial(n)
  9. # and the fact that the sigma function is multiplicative with:
  10. # sigma_m(p^k) = (p^(m*(k+1)) - 1)/(p^m - 1)
  11. # See also:
  12. # https://oeis.org/A001142
  13. # https://oeis.org/A323444
  14. # Paper:
  15. # Jeffrey C. Lagarias, Harsh Mehta
  16. # Products of binomial coefficients and unreduced Farey fractions
  17. # https://arxiv.org/abs/1409.4145
  18. # https://projecteuler.net/problem=650
  19. # Runtime: 29.965s
  20. use 5.020;
  21. use strict;
  22. use warnings;
  23. no warnings 'recursion';
  24. use experimental qw(signatures);
  25. use ntheory qw(powmod invmod mulmod forprimes todigits vecsum);
  26. sub p650 ($n, $m) {
  27. my @D = (1);
  28. forprimes {
  29. my $p = $_;
  30. my $fp_acc = 0;
  31. my $p_inv = invmod($p - 1, $m);
  32. foreach my $k ($p .. $n) {
  33. my $fp = ($k - vecsum(todigits($k, $p))) / ($p - 1);
  34. my $e = $fp * ($k - 1) - 2 * $fp_acc;
  35. $D[$k - 1] = mulmod($D[$k - 1] // 1, mulmod(powmod($p, $e + 1, $m) - 1, $p_inv, $m), $m);
  36. $fp_acc += $fp;
  37. }
  38. } $n;
  39. my $sum = 0;
  40. foreach my $d (@D) {
  41. $sum += $d;
  42. $sum %= $m;
  43. }
  44. return $sum;
  45. }
  46. say p650(20_000, 1000000007);