Ключом к этим задачам с большим числом модулей является не вычисление полного результата перед выполнением модуля. Вы должны уменьшить модуль на промежуточных шагах, чтобы число было небольшим:
500! / 20! = 21 * 22 * 23 * ... * 500
21 * 22 * 23 * 24 * 25 * 26 * 27 = 4475671200
4475671200 mod 1000000007 = 475671172
475671172 * 28 mod 1000000007 = 318792725
318792725 * 29 mod 1000000007 = 244988962
244988962 * 30 mod 1000000007 = 349668811
...
31768431 * 500 mod 1000000007 = 884215395
500! / 20! mod 1000000007 = 884215395
Вам не нужно уменьшать модуль на каждом шаге.Просто делайте это достаточно часто, чтобы число не становилось слишком большим.
Обратите внимание, что максимальное значение long
равно 2 ^ 63 - 1. Таким образом, выполняется 64-битное умножение между двумя положительными целыми значениями (т.е. один из операндов long
) не будет переполнен long
.Вы можете безопасно выполнить оставшуюся операцию %
впоследствии (если она также является положительной) и при необходимости привести ее к целому числу.