754 Product of Gauss Factorials.pl 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. #!/usr/bin/perl
  2. # Product of Gauss Factorials
  3. # https://projecteuler.net/problem=754
  4. # See also:
  5. # https://oeis.org/A001783
  6. use 5.014;
  7. use strict;
  8. use warnings;
  9. use ntheory qw(:all);
  10. use List::Util qw(reduce);
  11. use experimental qw(signatures);
  12. sub squarefree_divisors {
  13. my ($n) = @_;
  14. my @d = (1);
  15. my @pp = map { $_->[0] } factor_exp($n);
  16. foreach my $p (@pp) {
  17. push @d, map { $_ * $p } @d;
  18. }
  19. @d;
  20. }
  21. sub F ($n, $m) {
  22. my $prod = 1;
  23. foreach my $k (1 .. $n) {
  24. if (is_prime($k)) {
  25. $prod = mulmod($prod, factorialmod($k - 1, $m), $m);
  26. }
  27. else {
  28. $prod = mulmod(
  29. mulmod($prod, powmod($k, euler_phi($k), $m), $m),
  30. (
  31. reduce { mulmod($a, $b, $m) }
  32. map { powmod(divmod(factorialmod($k / $_, $m), powmod($k / $_, $k / $_, $m), $m), moebius($_), $m) }
  33. squarefree_divisors($k)
  34. ),
  35. $m
  36. );
  37. }
  38. }
  39. return $prod;
  40. }
  41. F(10, next_prime(powint(10, 20))) == 23044331520000
  42. or die "error!";
  43. #say F(1e3, 1000000007); # takes 0.09s
  44. #say F(1e4, 1000000007); # takes 0.6s
  45. #say F(1e5, 1000000007); # takes 24s
  46. say F(1e8, 1000000007);