\(\text{Problem}:\)[MtOI2018]情侣?给我烧了!
\(\text{Solution}:\)
设 \(f_{k}\) 表示恰好有 \(k\) 对情侣是和睦的方案数,\(g_{k}\) 表示钦定有 \(k\) 对情侣是和睦的方案数。考虑 \(g_{k}\) 的组合意义,在 \(n\) 对情侣中选 \(k\) 对(无序),在 \(n\) 排座位中选 \(k\) 排(有序),情侣之间有 \(2^{k}\) 种坐法,剩余人乱坐。故有:
\[\begin{aligned} g_{k}&=\binom{n}{k}\binom{n}{k}k!\cdot 2^{k}(2n-2k)!\\ f_{k}&=\sum\limits_{i=k}^{n}(-1)^{i-k}\binom{i}{k}g_{i}\\ &=\sum\limits_{i=k}^{n}(-1)^{i-k}\binom{i}{k}\binom{n}{i}\binom{n}{i}\cdot i!\cdot 2^{i}\cdot (2n-2i)!\\ &=\sum\limits_{i=k}^{n}(-1)^{i-k}\frac{n!n!}{k!(i-k)!(n-i)!(n-i)!}\cdot 2^{i}\cdot (2n-2i)!\\ &=\frac{n!n!\cdot 2^{k}}{k!}\sum\limits_{i=0}^{n-k}(-1)^{i}\frac{1}{i!(n-k-i)!(n-k-i)!}\cdot 2^{i}\cdot (2n-2k-i)! \end{aligned} \]现在 \(\sum\) 内式子的值只与 \(n-k\) 的大小有关,故直接枚举 \(n-k\),预处理 \(\sum\) 内的值即可。总时间复杂度 \(O(n^2+Tn)\)。
\(\text{Code}:\)
#include <bits/stdc++.h>
#pragma GCC optimize(3)
//#define int long long
#define ri register
#define mk make_pair
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define is insert
#define es erase
#define vi vector<int>
#define vpi vector<pair<int,int>>
using namespace std; const int N=2010, Mod=998244353;
inline int read()
{
int s=0, w=1; ri char ch=getchar();
while(ch<'0'||ch>'9') { if(ch=='-') w=-1; ch=getchar(); }
while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+(ch^48), ch=getchar();
return s*w;
}
int n,fac[N+5],inv[N+5],pw[N+5],a[N];
inline int ksc(int x,int p) { int res=1; for(;p;p>>=1, x=1ll*x*x%Mod) if(p&1) res=1ll*res*x%Mod; return res; }
inline void Init()
{
fac[0]=1;
for(ri int i=1;i<=N;i++) fac[i]=1ll*fac[i-1]*i%Mod;
inv[N]=ksc(fac[N],Mod-2);
for(ri int i=N;i;i--) inv[i-1]=1ll*inv[i]*i%Mod;
pw[0]=1;
for(ri int i=1;i<=N;i++) pw[i]=pw[i-1]*2%Mod;
for(ri int i=0;i<=1000;i++)
for(ri int j=0;j<=i;j++)
{
int w=1ll*inv[j]*inv[i-j]%Mod*inv[i-j]%Mod*pw[j]%Mod*fac[i*2-j*2]%Mod;
if(j&1) a[i]=(a[i]-w+Mod)%Mod;
else a[i]=(a[i]+w)%Mod;
}
}
signed main()
{
Init();
for(ri int T=read();T;T--)
{
n=read();
for(ri int i=0;i<=n;i++)
{
printf("%d\n",1ll*fac[n]*fac[n]%Mod*pw[i]%Mod*inv[i]%Mod*a[n-i]%Mod);
}
}
return 0;
}