传送门
来一发容斥做法。
f
i
,
j
f_{i,j}
fi,j表示
i
i
i对位置
j
j
j对人配对成功的方案。
然后
f
n
,
k
=
(
C
n
k
)
2
2
k
k
!
∑
i
=
0
k
(
−
1
)
i
(
C
n
−
k
i
)
2
i
!
2
i
(
2
n
−
2
k
−
2
i
)
!
=
(
C
n
k
)
2
2
k
k
!
g
(
n
,
k
)
=
(
C
n
k
)
2
2
k
k
!
g
(
n
−
1
,
k
−
1
)
\begin{aligned}f_{n,k}=&(C_n^k)^22^kk!\sum\limits_{i=0}^k(-1)^i(C_{n-k}^i)^2i!2^i(2n-2k-2i)!\\=&(C_n^k)^22^kk!g(n,k)\\=&(C_n^k)^22^kk!g(n-1,k-1)\end{aligned}
fn,k===(Cnk)22kk!i=0∑k(−1)i(Cn−ki)2i!2i(2n−2k−2i)!(Cnk)22kk!g(n,k)(Cnk)22kk!g(n−1,k−1)
然后只用预处理出
g
0
,
0
,
g
1
,
0
,
.
.
.
,
g
n
,
0
g_{0,0},g_{1,0},...,g_{n,0}
g0,0,g1,0,...,gn,0即可。
然而预处理是
O
(
n
2
)
O(n^2)
O(n2)的过不了加强版,还得重新想办法。
代码:
#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int rlen=1<<18|1;
inline char gc(){
static char buf[rlen],*ib,*ob;
(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));
return ib==ob?-1:*ib++;
}
inline int read(){
int ans=0;
char ch=gc();
while(!isdigit(ch))ch=gc();
while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
return ans;
}
const int mod=998244353;
typedef long long ll;
inline int add(int a,int b){return (a+=b)<mod?a:a-mod;}
inline int dec(int a,int b){return (a-=b)<0?a+mod:a;}
inline int mul(int a,int b){return (ll)a*b%mod;}
inline void Add(int&a,int b){(a+=b)<mod?a:a-=mod;}
inline void Dec(int&a,int b){(a-=b)<0?a+=mod:a;}
inline void Mul(int&a,int b){a=(ll)a*b%mod;}
inline int ksm(int a,int p){int ret=1;for(;p;p>>=1,Mul(a,a))if(p&1)Mul(ret,a);return ret;}
const int N=2005;
int n,fac[N],ifac[N],pw[N],f[N];
inline int C(int n,int m){return (ll)fac[n]*ifac[m]%mod*ifac[n-m]%mod;}
int main(){
fac[0]=fac[1]=ifac[0]=ifac[1]=1,pw[0]=1,pw[1]=2;
for(ri i=2;i<=2000;++i)fac[i]=mul(fac[i-1],i),ifac[i]=mul(ifac[mod-mod/i*i],mod-mod/i);
for(ri i=2;i<=2000;++i)Mul(ifac[i],ifac[i-1]),pw[i]=add(pw[i-1],pw[i-1]);
for(ri n=0;n<=1000;++n){
int t=0;
for(ri ad,i=0;i<=n;++i){
ad=mul(mul(mul(C(n,i),C(n,i)),fac[i]),mul(pw[i],fac[2*(n-i)]));
i&1?Dec(t,ad):Add(t,ad);
}
f[n]=t;
}
for(ri tt=read();tt;--tt){
n=read();
for(ri k=0;k<=n;++k)cout<<mul(f[n-k],mul(mul(C(n,k),C(n,k)),mul(fac[k],pw[k])))<<'\n';
}
return 0;
}