сумма факториалов

[Условие задачи](с сика 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;
}

Асимптотика решения .

Last change: 2023-10-13, commit: d9af9f8