сумма факториалов
[Условие задачи](с сика TODO)
Условие
Вам дано число , ваша задача посчитать сумму факториалов : . Ограничение на до . Ответ выведите по простому модулю .
Решение
Решение
Разбор условия
Ответ по
модулю
часто встречается в условие для того чтобы участники могли оперировать в диапазоне целочисленных типов языка программирования. Но в большинстве случаев модулем является1000000007
— .
На самом деле, модуль используется для того, чтобы облегчить, а не усложнить вычисления. Это может показаться нелогичным, но как только вы узнаете, как работает модульная арифметика, вы поймёте, почему.
простой
модуль, так как это связано с модульной арифметикой (я сам особо не могу ответить на этот вопрос) (скоро перепишу это)
Решение в лоб
Факториал числа можно посчитать за простым циклом.
В коде ниже используется модуль, как видите это не страшно
1LL
это переменнаяlong long
равная1
,LL
суффиксный литерал типа. Если умножить дваint
'а между собой, то может произойти переполнение, поэтому надо считать вlong long
. При умножениеlong long
наint
получаетсяlong long
.
По уму люди делают функции
add(a, b)
иmult(a, b)
которые уже внутри складывают и умножают по модулю соответственно.
Очевидно, что число типа
long long
взятое по модулю1e9 + 7
имеет диапазон и влазит вint
.
int mod = 1e9 + 7;
int factorial(int n) {
int res = 1;
for (int i = 1; i <= n; i++) {
res = (1LL * res * i) % mod;
}
return res;
}
Тогда чтобы решить задачу, можно раз запустить функцию factorial
:
int sum = 0;
for (int i = 1; i <= n; i++) {
sum = (sum + factorial(i)) % mod;
}
cout << sum;
Хочу вас расстроить, асимптотика этого решения .
Подумайте, как особо ничего не переписывая сделать асимптотику .
Быстрое решение
Достаточно вспомнить определение факториала :
Из определение следует, что
Значит, для подсчёта следующего факториала, достаточно знать факториал предыдущего числа.
Код полного решения занимает пару строк. Рекомендую разобраться подробно в нём :
void solve() {
int n, mod = 1e9 + 7, fac = 1, sum = 0;
cin >> n;
for (int i = 1; i <= n; i++) {
fac = (1LL * fac * i) % mod;
sum = (sum + fac) % mod;
}
cout << sum;
}
Асимптотика решения .