Кількість хлопчиків у класі дорівнює b = m - n. Оскільки хлопчики всі відрізняються, число способів їх розставити дорівнює
Навколо хлопчиків утворюється b + 1 позиція, куди можна поставити дівчаток:
Всього дівчаток . Тому нам слід вибрати різних позицій із b + 1, куди можна поставити дівчаток:
Якщо n > b + 1, то відповідь дорівнює .
Дівчатка також відрізняються, отже їх можна переставляти.
Таким чином, кількість способів, якими можна розставити в ряд усіх учнів, дорівнює
Приклад
Розглянемо тест m = 3, n = 2.
Число хлопчиків дорівнює b = m - n = 3 - 2 = 1. Відповідь дорівнює
Розглянемо тест m = 4, n = 2.
Число хлопчиків дорівнює b = m - n = 4 - 2 = 2. Відповідь дорівнює
Реалізація алгоритму
Оголосимо масиви:
містить факторіали чисел по модулю ,
factinv містить обернені значення до цих факторіалів по модулю :
#define MAX 1000001
#define MOD 1000000007
ll fact[MAX], factinv[MAX];Функція pow обчислює степінь числа по модулю: x^n~mod~p.
ll pow(ll x, ll n, ll p)
{
if (n == 0) return 1;
if (n % 2 == 0) return pow((x * x) % p, n / 2, p);
return (x * pow(x, n - 1, p)) % p;
}Функція inverse знаходить число, обернене до по простому модулю . Так як — просте число, то за малою теоремою Ферма виконується рівність:
Його можна переписати у вигляді (x \cdot x^{p - 2})~mod~p = 1, звідки слідує, що оберненим до є число x^{p - 2}~mod~p.
ll inverse(ll x, ll p)
{
return pow(x, p - 2, p);
}Функція Cnk обчислює біноміальний коефіцієнт за формулою:
ll Cnk(int n, int k)
{
return ((fact[n] * factinv[k]) % MOD * factinv[n - k]) % MOD;
}Основна частина програми. Заповнюємо масиви факторіалів та обернених факторіалів factinv.
fact[0] = 1;
for (i = 1; i < MAX; i++)
fact[i] = (fact[i - 1] * i) % MOD;
factinv[0] = 1;
for (i = 1; i < MAX; i++)
factinv[i] = inverse(fact[i], MOD);Читаємо кількість тестів .
scanf("%d", &tests);
while (tests--)
{Читаємо дані поточного тесту.
scanf("%d %d", &m, &n);Обчислюємо кількість хлопчиків b = m - n.
b = m - n;Обчислюємо та виводимо відповідь за формулою:
res = ((fact[n] * fact[b]) % MOD * Cnk(b + 1, n)) % MOD;
printf("%lld\n", res);
}