Поскольку 1000000003 = 23 * 307 * 141623, вы можете рассчитать (n выбирает k) mod 23, 307 и 141623, а затем применить теорему китайского напоминания [1].При расчете n !, k!и (nk) !, вы должны рассчитывать каждый мод 23, 307 и 141623 каждый шаг, чтобы предотвратить переполнение.
Таким образом, вы должны избегать переполнения даже на 32-битных машинах.
Небольшое улучшение будетбыть для вычисления (n выбирает k) мод 141623 и 7061 (23 * 307) (редактировать: но это может быть немного сложно вычислить обратный модуль 7061, поэтому я бы не стал это делать)
I 'извините за мой плохой английский.
[1] http://en.wikipedia.org/wiki/Chinese_remainder_theorem
Edit2: Еще одна потенциальная проблема, которую я обнаружил, - это вычисление n!mod 23 (например) это, вероятно, будет 0, но это не означает, что (n выбирает k) равно 0 mod 23, поэтому вы должны посчитать, сколько раз 23 делит n !, (nk)!и к!перед расчетом (n выбирает k).Вычислить это легко, р делит п!ровно пол (н / п) + пол (н / п²) + ... раз.Если так получится, что 23 делит n!в то же время он делит к!и (nk) !, вы продолжаете вычислять (n выбирает k) mod 23, делив его на 23 каждый множитель каждый раз. То же самое относится к 307, но не к 141623