题目链接

https://www.luogu.org/problemnew/show/P4931

题解

以下部分是我最开始的想法。

对于每一个 \(k\),满足恰好有 \(k\) 对情侣和睦的方案数为

\[\binom{n}{k} × \binom{n}{k} × k! × 2^k × f_{n - k}
\]

其中,\(f_x\) 表示 \(x\) 对情侣坐 \(x\) 排座位且没有任何一对情侣坐在同一排的方案数。

上述式子的意义为:从 \(n\) 对情侣中选出 \(k\) 对作为和睦的,再从 \(n\) 排中选出 \(k\) 排供这 \(k\) 对情侣就坐,方案数为 \(\binom{n}{k} × \binom{n}{k}\)。由于 \(k\) 对情侣就坐顺序可以不一致,且每队情侣内部双方也可以交换座位,因此方案数为 \(k! × 2^k\)。再乘以剩下的 \(n - k\) 对情侣均不出现和睦的方案数即为最终答案。

现在问题在于如何求出 \(f_x\)。考虑容斥,\(f_x=\) 任意就坐的方案数\(-\)至少存在一对情侣和睦的方案数\(+\)至少存在两对情侣和睦的方案数\(-\)至少存在三对情侣和睦的方案数\(...\)

那么做和上面类似的分析,我们可以得到:

\[f_x = \sum_{i = 0}^{x} (-1)^i × \binom{x}{i} × \binom{x}{i} × i!× 2^i × (2×(x - i))!
\]

上述式子最后的 \((2×(x - i))!\) 表示不强制和睦的 \(x - i\) 对情侣随意就坐的方案数。

总预处理的复杂度为 \(O(n^2)\)。

虽然这种容斥的想法很自然,但是时间复杂度并不优秀。我们需要找更好的办法求 \(f_x\)。于是就有了加强版。

在此之前,我们先回忆一下错位排列数的递推式:

\[D_n = (n - 1)(D_{n - 1} + D_{n - 2})(n \geq 2)
\]

《组合数学》上对其的证明大概是这样的:

我们想要求得 \(D_n\),考虑长度为 \(n\) 的排列的第一个位置,有 \(2, 3, 4, \cdots, n\) 共 \(n - 1\) 种填法。很显然的是,无论以谁作为开头,方案数都是一样的,因此我们只需算出以任意一个数开头的方案数,乘以 \(n - 1\) 就好了。我们假设第一位填了 \(2\),那么第二个位置可以填 \(1, 3, 4, \cdots, n\)。如果填了 \(1\),那么剩下的部分就是一个 \(3, 4, \cdots , n\) 的错位排列,方案数为 \(D_{n - 2}\);如果不填 \(1\),那么这一位的 \(1\) 和 \(3, 4, \cdots, n\) 共同构成了长度为 \(n - 1\) 的错位排列,方案数为 \(D_{n - 1}\),因此有 \(D_n = (n - 1)(D_{n - 1} + D_{n - 2})(n \geq 2)\)。

我们将其推广到这个题。若 \(n\) 对情侣要坐 \(n\) 排座位,考虑第一排座位必须坐两个不互为情侣的人,共有 \(2n \times (2n - 2) = 4n(n - 1)\) 种方案(第一个人可以是 \(2n\) 个人里面的任意一个,第二个人可以是剩下的 \(2n - 1\) 个人中除了第一个人的配偶的任意一个)。接下来共有两种情况:若第一排的两个人对应的配偶也坐到了同一排,那么剩下的 \(n - 2\) 对情侣就坐且不满足同排互为情侣的方案数为 \(f_{n - 2}\),由于第一排的两个人对应的配偶可以任选 \(n - 1\) 排中的一排就坐,且可以互换位置,因此该情况下总方案数为 \(2(n - 1)f_{n - 2}\);若第一排的两个人对应的配偶没有坐到同一排,那么我们可以把他们也视为一对情侣,他们和剩下的 \(n - 2\) 对情侣就坐合法的方案数为 \(f_{n - 1}\)。

这样,我们就得到了 \(f\) 的递推式:\(f_n = 4n(n - 1)(f_{n - 1} + 2(n - 1)f_{n - 2})(n \geq 2)\),边界为 \(f_0 = 1, f_1 = 0\)。此题就可以在 \(O(n)\) 的时间内完成预处理了。

代码

#include<bits/stdc++.h>

using namespace std;

#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define debug(...) fprintf(stderr, __VA_ARGS__) typedef long long ll;
typedef long double ld;
typedef unsigned int uint;
typedef pair<int, int> pii;
typedef unsigned long long ull; template<typename T> inline void read(T& x) {
char c = getchar();
bool f = false;
for (x = 0; !isdigit(c); c = getchar()) {
if (c == '-') {
f = true;
}
}
for (; isdigit(c); c = getchar()) {
x = x * 10 + c - '0';
}
if (f) {
x = -x;
}
} template<typename T, typename... U> inline void read(T& x, U&... y) {
read(x), read(y...);
} template<typename T> inline bool checkMax(T& a, const T& b) {
return a < b ? a = b, true : false;
} template<typename T> inline bool checkMin(T& a, const T& b) {
return a > b ? a = b, true : false;
} const int N = 5e6 + 10, mod = 998244353; inline void mul(int& x, int y) {
x = 1ll * x * y % mod;
} inline int qpow(int v, int p) {
int res = 1;
for (; p; p >>= 1, mul(v, v)) {
if (p & 1) {
mul(res, v);
}
}
return res;
} int fac[N], invfac[N], pow2[N], f[N]; inline int binom(int n, int m) {
return 1ll * fac[n] * invfac[m] % mod * invfac[n - m] % mod;
} void init(int n) {
fac[0] = invfac[0] = pow2[0] = f[0] = 1;
for (register int i = 1; i <= n; ++i) {
fac[i] = 1ll * fac[i - 1] * i % mod;
pow2[i] = (pow2[i - 1] << 1) % mod;
if (i > 1) {
f[i] = 4ll * i * (i - 1) % mod * (f[i - 1] + 2ll * (i - 1) * f[i - 2] % mod) % mod;
}
}
invfac[n] = qpow(fac[n], mod - 2);
for (register int i = n - 1; i; --i) {
invfac[i] = 1ll * invfac[i + 1] * (i + 1) % mod;
}
} int main() {
init(5000000);
int t; read(t);
for (register int kase = 1; kase <= t; ++kase) {
int n, k; read(n, k);
printf("%lld\n", 1ll * binom(n, k) * binom(n, k) % mod * fac[k] % mod * pow2[k] % mod * f[n - k] % mod);
}
return 0;
}

luogu4931. 情侣?给我烧了!(加强版)(错位排列)的更多相关文章

  1. [Luogu4921]情侣?给我烧了![错位排列]

    题意 题意很清楚 \滑稽 分析 对于每一个询问 \(k\) ,记 \(g(x)\) 表示 \(x\) 对情侣都错开的方案总数,那么答案可以写成如下形式: \[ {ans}_k= \binom{n}{k ...

  2. HDU_2049——部分错位排列,概率论

    Problem Description 国庆期间,省城HZ刚刚举行了一场盛大的集体婚礼,为了使婚礼进行的丰富一些,司仪临时想出了有一个有意思的节目,叫做"考新郎",具体的操作是这样 ...

  3. HDU_2048——全错位排列递推公式

    Problem Description HDU 2006'10 ACM contest的颁奖晚会隆重开始了! 为了活跃气氛,组织者举行了一个别开生面.奖品丰厚的抽奖活动,这个活动的具体要求是这样的:首 ...

  4. 【数论·错位排列】bzoj4517 排列计数

    4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 1428  Solved: 872[Submit][Statu ...

  5. BZOJ.4517.[SDOI2016]排列计数(错位排列 逆元)

    题目链接 错位排列\(D_n=(n-1)*(D_{n-1}+D_{n-2})\),表示\(n\)个数都不在其下标位置上的排列数. 那么题目要求的就是\(C_n^m*D_{n-m}\). 阶乘分母部分的 ...

  6. Luogu4931 情侣?给我烧了!(加强版)【生成函数】

    题目链接:洛谷 大家一起 日 ♂ % EI 设\(D_i\)表示\(k=0\)时的答案.那么 \[ f(n,k)=\binom{n}{k}^2D_{n-k}k!2^k \] 意义是选择\(k\)对情侣 ...

  7. [luogu4931]情侣?给我烧了!

    题解 有\(i\)对情侣全都不和谐那里推不出来只好写了一个暴力容斥然后大力卡常卡过去了== 容斥太过暴力,还是说正解吧 可以考虑直接计算\(n\)对情侣有\(k\)对和谐的方案数 设\(g[i]\)表 ...

  8. 洛谷P4931 情侣!给我!烧了! 数论

    正解:数论 解题报告: 传送门 这题,想不到就很痛苦,但是理解了之后还是觉得也没有很难,,,毕竟实现不难QAQ 首先关于前面k对情侣的很简单,就是C(n,k)*C(n,k)*A(k,k)*2k 随便解 ...

  9. [BZOJ4517][SDOI2016]排列计数(错位排列)

    4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 1616  Solved: 985[Submit][Statu ...

随机推荐

  1. SQL SERVER 2008权限配置

    我要的结果是这样:只能有查询表的权限,而且还要有运行SQL Server Profiler的权限.这样才能跟踪发现问题,当然解决问题是另外一回事,即不能有修改和更新存储过程的权限. 我在分配角色成员时 ...

  2. C#连接Mysql数据库 MysqlHelper.cs文件

    mysql.data.dll下载_c#连接mysql必要插件mysql.data.dll是C#操作MYSQL的驱动文件,是c#连接mysql必要插件,使c#语言更简洁的操作mysql数据库.当你的电脑 ...

  3. opennebula 安装指定参数

    [root@opennebula opennebula-]# ./install.sh -u oneadmin -g oneadmin -k -d /home/oneadmin/ -u 指定用户-g ...

  4. 2.python IP/DNS地址处理之IPy/Dnspython模块

     1.IPy模块 在IP地址规划中,涉及到计算大量的IP地址,包括网段.网络掩码.广播地址.子网数.IP类型等,即便是专业的网络人员也要进行繁琐的计算,而IPy模块提供了专门针对IPV4地址与IPV6 ...

  5. .html与.text的异同

    .html与.text的方法操作是一样,只是在具体针对处理对象不同 .html处理的是元素内容,.text处理的是文本内容 .html只能使用在HTML文档中,.text 在XML 和 HTML 文档 ...

  6. 2.8.2 并发下的ArrayList,以及源码分析

    package 第二章.并发下的ArrayList; import java.util.ArrayList;import java.util.List; /** * Created by zzq on ...

  7. (转)基于 WPF + Modern UI 的 公司OA小助手 开发总结

    原文地址:http://www.cnblogs.com/rainlam163/p/3365181.html 前言: 距离上一篇博客,整整一个月的时间了.人不能懒下来,必须有个阶段性的总结,算是对我这个 ...

  8. MySQL性能调优与架构设计——第4章 MySQL安全管理

    第4章 MySQL安全管理 前言 对于任何一个企业来说,其数据库系统中所保存数据的安全性无疑是非常重要的,尤其是公司的有些商业数据,可能数据就是公司的根本,失去了数据的安全性,可能就是失去了公司的一切 ...

  9. Backbone.js 0.9.2 中文解释

    // Backbone.js 0.9.2 // (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc. // Backbone may be freely ...

  10. Sobel算法

    最近看了一些Sobel算法,并试了一下,源码如下: private void Sobel(Bitmap img) { int width = img.Width; int height = img.H ...