问题描述
小R正在研究一种特殊的排列,称为“好排列”。一个排列被称为“好排列”,当且仅当其中所有相邻的两个数的乘积均为偶数。现在给定一个正整数 nn,小R想知道,长度为 nn 的好排列共有多少种。由于结果可能非常大,你需要将结果对 109+7109+7 取模后输出。
测试样例
样例1:
输入:
n = 2
输出:2
样例2:
输入:
n = 3
输出:2
样例3:
输入:
n = 5
输出:12
#include <iostream>
#include <vector>
using namespace std;
const int MOD = 1e9 + 7;
const int MAXN = 100005;
vector<long long> fac(MAXN), inv_fac(MAXN);
// 快速幂
long long qpow(long long a, long long b) {
long long res = 1;
while (b) {
if (b & 1)
res = res * a % MOD;
a = a * a % MOD;
b >>= 1;
}
return res;
}
// 初始化阶乘和逆元
void init() {
fac[0] = inv_fac[0] = 1;
for (int i = 1; i < MAXN; ++i) {
fac[i] = fac[i - 1] * i % MOD;
inv_fac[i] = qpow(fac[i], MOD - 2);
}
}
long long C(int n, int k) {
if (k < 0 || k > n)
return 0;
return fac[n] * inv_fac[k] % MOD * inv_fac[n - k] % MOD;
}
int solution(int n) {
// PLEASE DO NOT MODIFY THE FUNCTION SIGNATURE
static bool initialized = false;
if (!initialized) {
init();
initialized = true;
}
int odd_cnt = (n + 1) / 2;
int even_cnt = n / 2;
if (odd_cnt > even_cnt + 1)
return 0;
long long res = C(even_cnt + 1, odd_cnt);
res = res * fac[odd_cnt] % MOD;
res = res * fac[even_cnt] % MOD;
return (int)res;
}
int main() {
std::cout << (solution(2) == 2) << std::endl;
std::cout << (solution(3) == 2) << std::endl;
std::cout << (solution(5) == 12) << std::endl;
}