BZOJ 4517 [SDOI2016] 排列计数(组合 错排)

题目

求有多少种长度为 n 的序列 A,满足以下条件:
1 ~ n 这 n 个数在序列中各出现了一次
若第 i 个数 A[i] 的值为 i,则称 i 是稳定的。序列恰好有 m 个数是稳定的
满足条件的序列可能很多,序列数对 10^9+7 取模。

题解

n个选m个,剩下的错排。直接预处理组合数和错排就行了。

CODE

#pragma GCC optimize ("O2")
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod = 1e9 + 7;
const int MAXN = 1000005;
int n, m, fac[MAXN], inv[MAXN], D[MAXN];
inline int C(int n, int m) { return n < m ? 0 : 1ll * fac[n] * inv[m] % mod * inv[n-m] % mod; }
inline void pre(int N) {
	inv[0] = inv[1] = fac[0] = fac[1] = 1;
	for(int i = 2; i <= N; ++i)
		inv[i] = 1ll * (mod - mod/i) * inv[mod%i] % mod,
		fac[i] = 1ll * fac[i-1] * i % mod;
	D[0] = 1, D[1] = 0;
	for(int i =2; i <= N; ++i)
		inv[i] = 1ll * inv[i-1] * inv[i] % mod,
		D[i] = 1ll * (i-1) * (D[i-1] + D[i-2]) % mod; 
}
int main () {
	pre(MAXN-5);
	int T; scanf("%d", &T);
	while(T-->0) {
		scanf("%d%d", &n, &m);
		printf("%d
", 1ll * C(n, m) * D[n-m] % mod);
	}
}
原文地址:https://www.cnblogs.com/Orz-IE/p/12039228.html