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

题意

题意很清楚 \滑稽

分析

  • 对于每一个询问 \(k\) ,记 \(g(x)\) 表示 \(x\) 对情侣都错开的方案总数,那么答案可以写成如下形式:
    \[ {ans}_k= \binom{n}{k}\times A_n^k\times 2^k\times g(n-k) \]
  • 考虑如何求 \(g(x)\) (一个错位排列)。
  • 考虑第一排,一共有三种情况:两男两女或者一男一女(不配对)。
    • 两男:顺次选出两男的方案数为 \(x(x-1)\) ,然后考虑他们的配偶在之后的配对情况:

      • 如果强制不配对,那么把她们看成一对情侣来保证之后的过程中不配对(gay里gay气),即 \(g(x-1)\) 。
      • 如果强制配对,那么在剩下的 \(x-1\) 排中选择一排,两人顺序可以交换,转移为 \(2(x-1)\times g(x-2)\)。
    • 两女:方案数显然和两男的情况相同。
    • 一男一女:枚举一男一女,可以交换顺序的方案数为 \(x(x-1)\) ,转移其实是一样的,
  • 所以我们得到:\(g(x)=4x(x-1)\times[g(x-1)+2(x-1)\times g(x-2)]\) 。
  • 单次处理 \(g\) 复杂度 \(O(n)\) ,每次回答枚举 \(k\) 复杂度 \(O(n)\) ,总时间复杂度为 \(O(n)\) 。

代码

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pb push_back
typedef long long LL;
inline int gi(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
    return x*f;
}
template<typename T>inline bool Max(T &a,T b){return a<b?a=b,1:0;}
template<typename T>inline bool Min(T &a,T b){return b<a?a=b,1:0;}
const int N=2004,mod=998244353;
int T,n;
LL fac[N],inv[N],invfac[N],bin[N],g[N];
void add(LL &a,LL b){a+=b;if(a>=mod) a-=mod;}
LL Pow(LL a,LL b){
    LL res=1ll;
    for(;b;b>>+1,a=a*a%mod) if(b&1) res=res*a%mod;
    return res;
}
LL C(int n,int m){
    return fac[n]*invfac[n-m]%mod*invfac[m]%mod;
}
int main(){
    fac[0]=invfac[0]=inv[1]=bin[0]=1;
    rep(i,1,N-1){
        if(i^1) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
        fac[i]=fac[i-1]*i%mod;
        invfac[i]=invfac[i-1]*inv[i]%mod;
        bin[i]=bin[i-1]*2%mod;
    }

    g[0]=1,g[1]=0;
    rep(n,2,1000) g[n]=4ll*n*(n-1)%mod*(g[n-1]+2*(n-1)*g[n-2])%mod;

    T=gi();
    while(T--){
        n=gi();
        rep(k,0,n) printf("%lld\n",C(n,k)*C(n,k)%mod*fac[k]%mod*bin[k]%mod*g[n-k]%mod);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/yqgAKIOI/p/9807188.html

时间: 2024-10-09 05:14:53

[Luogu4921]情侣?给我烧了![错位排列]的相关文章

luogu4931.情侣?给我烧了!(加强版)(错位排列)

题目链接 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封不同的信及相应的n个不同的信封,他把这n封信都装错了信封,问都装错信封的装法有多少种? 用a.b.c,d--表示n份相应的写好的信纸,A.B.C,D--表示写着n位友人名字的信封,错装的总数为记作f(n). 假设把a错装进B中,然后接下来我们可以分为两种情况, 第一种是b错装进了A中,那么问题就变为c,d,e-..n-2个信纸放入C,D,E--n-2个信封时完全放错时完全装错有多少种,有f(n-2)种 第二种是b错装

《程序设计中的组合数学》——全错位排列

承接上文,这次以递推的思维,介绍组合学当中一个很经典的问题. 这个问题最开始由瑞士数学家欧拉提出,原始的问题被叫做“装信封问题”,问题的大意就是:有n封信和n封它们各自对应的信封,如果邮递员想要把每封信都放在不属于这封信的信封,那么请问有多少种排法.(这邮递员真无聊)  想必这个问题在中学阶段数学的[排列组合]都有过接触,但是我记忆非常深刻的是,老师讲到这个模型,自己找了一下n = 5的情况就停止了,然后让大家把前面的数字序列背下来.今日故地重游不禁觉得老师教的好坑爹,搞学习还是要亲历亲为自主探

hdoj 2049 不容易系列之(4)——考新郎 【全错位排列】【组合数】

方法如题. 全错位排列 不容易系列之(4)--考新郎 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 21347    Accepted Submission(s): 7857 Problem Description 国庆期间,省城HZ刚刚举行了一场盛大的集体婚礼,为了使婚礼进行的丰富一些,司仪临时想出了有一个有意思的节目,叫做"考新郎

关于错位排列

今天弄了一下错位排列,似乎挺简单的... 错位排列问题的描述大致如下:给定n个信封以及n个信,每个信只能容纳在,第i号信需要放在第i号信封里,现在所有信封的位置都是错误的,求不同的错误方案数. 因为第i号信是不在第i号信封里面的,这样的话我们可以模拟出以下n*n的矩阵(其中1表示信封错误的位置不能是此处): 1,0,0,0 不难看出来,对于第一行来说我们有3种不同的方案,在某个点被占据时,其所在的排,列,都没有意义了,这样的话我们可以得到3个新的矩阵: 0,1,0,0 1: 0,0,0 2:0,

生成所有错位排列的算法

所谓N元错位排列,就是指对应于1,2,--,N的N元排列Im(m=1,2,---,N),满足Im!=m,算法的目的是构造出所有这样的错位排列,依据的基本思想是回溯法,在沿栈向下试探的过程中逐步扩大部分错位排列的规模,当发现无法找到下一个部分错位排列的元素时就向上回溯,继续试探,当栈空间首元素stack[0]==N+1时,表明首元素为2,--,N的所有错位排列已全部试探得到,错位排列生成完毕,退出循环.这里给出算法,该算法生成对应于1,2,---,N的所有N元错位排列 代码(C++) 1 #inc

错位排列及有关例题

求n个数(不相同)错位排列的个数. 何为错位排列?定义如下:对于n的一个排列a1,a2,a3...an. 如何求解错位排列? 考虑动态规划的解法. 前i个元素时如何进行状态转移? (一)首先由于要求错位排列,第i个元素肯定不会放在自己的位置上,故第i个元素的位置有i-1种选择. (二)对于剩下的i-1个元素,选择其中的一个元素k.这时候k有两种选择: 1. 放在第i个元素的位置上,宏观上相当于i与k的位置互换了.而剩下的i-2个元素依然要求错位排列. 2. 不放在第i个元素的位置上,则相当于剩下

错位排列

问题: 一个人写了n封不同的信及相应的n个不同的信封,他把这n封信都装错了信封,问都装错信封的装法有多少种? 就是hdu2048 Solution: 采用递推的方法 记 \(n\) 个数的错排的方案为 \(f(n)\). 如果我们已经求出来前 \(n-1\) 个 \(f(n)\) ,现在考虑将第一个元素放在第 \(k\) 个元素的位置上,那么会有以下两种情况 第 \(k\) 个元素恰好到了第一个位置,那么对于 \([2,k-1]\cap [k+1,n]\) 内的 \(n-2\) 个元素可以与 \

Luogu4921/4931 情侣?给我烧了! 组合、递推

4921 4931 第一眼看着就像容斥,但是容斥不怎么好做-- 第二眼想到错排,结果错排公式糊上去错了-- 不难考虑到可以先选\(K\)对情侣坐在一起,剩下\(N-K\)对错排 选\(K\)对情侣坐在一起的方案数是: 选情侣的方案数\(C_N^K \times\)选椅子的方案数\(C_N^K\times\)情侣坐的椅子可以任意排列\(K!\times\)情侣之间可以互换位置\(2^K\)=\((C_N^K)^2K!2^K\) 然后考虑这个错排 实际上直接糊错排公式是很难对的,至少我不会直接用错排