10272. Уменьшите
до одного
Рассмотрим
список целых чисел L. Изначально L содержит все целые числа от 1 до n, каждое ровно один раз (позже в списке
могут появиться несколько копий некоторых чисел). Порядок элементов в L не
имеет значения. Вам необходимо выполнить следующую операцию n – 1 раз:
·
Выберите два элемента из списка, обозначим их x и y.
Они могут быть равными.
·
Удалите выбранные элементы из L.
·
Добавьте в список число x + y + x * y.
В
результате в списке останется ровно одно число. Найдите максимально возможное
значение этого числа. Поскольку ответ может быть большим, выведите его по
модулю 109 + 7.
Вход. Первая строка содержит
количество тестов t. Каждая из
следующих t строк содержит одно целое
число n (1 ≤ n ≤ 106).
Выход. Для каждого теста выведите
одно целое число – максимальное возможное значение последнего числа в списке,
вычисленное по модулю 109 + 7.
|
Пример
входа |
Пример
выхода |
|
|
3 1 2 4 |
1 5 119 |
|
математика
Сначала преобразуем
выражение:
x + y + x * y = y * (x + 1) + (x + 1) – 1 = (x + 1) * (y + 1) – 1
Теперь операция
выглядит как умножение двух чисел, увеличенных на 1, с последующим вычитанием
1.
Удалим из списка
числа x и y. Тогда в список будет вставлено число
(x + 1) * (y + 1) – 1
Далее удалим из
списка числа (x + 1) * (y + 1) – 1 и z. Тогда вставлено в список будет число
((x + 1) * (y + 1) – 1 + 1) * (z + 1)
– 1 =
(x + 1) * (y + 1) * (z + 1) – 1
Следуя этой аналогии,
можно утверждать, что если изначально
L = {a1, a2,
…, an},
то в конце останется
число
(a1 + 1) * (a2 + 1) * … * (an + 1) – 1
Поскольку
изначально L содержит все целые числа от 1 до n, в итоге получится число
(1 + 1)
* (2 + 1) * … * (n + 1) – 1 = (n + 1)! – 1
Результирующее число
определяется единственным образом и не зависит от порядка выполнения операций.
Реализация алгоритма
Объявим константы.
#define MOD 1000000007
#define MAX 1000002
Входные данные содержат несколько тестов. Объявим массив p, такой что p[i] = i!.
long long p[MAX];
Читаем количество тестов tests.
Вычисляем факториалы чисел и сохраняем их в массиве: p[i] = i!
scanf("%d", &tests);
p[1] = 1;
for (i = 2; i < MAX; i++)
p[i] = (p[i - 1] * i) % MOD;
Обрабатываем последовательно тесты.
while (tests--)
{
Для каждого входного значения n выводим ответ – значение (n + 1)! – 1.
scanf("%d", &n);
printf("%lld\n", p[n + 1] - 1);
}
Python реализация
Объявим константы.
MOD
= 1000000007
MAX
= 1000002
Вычисляем факториалы чисел и сохраняем их в списке: p[i] = i!
p =
[1] * MAX
for i in range(2,
MAX):
p[i] = (p[i - 1] *
i) % MOD
Читаем количество тестов tests.
tests
= int(input())
Обрабатываем последовательно тесты.
for _ in range(tests):
Для каждого входного значения n выводим ответ – значение (n + 1)! – 1.
n = int(input())
print(p[n + 1] - 1)