组合题。。。要推公式:
首先考虑和谐的k对情侣:
从n对中选出k对:C[n][k]。
从n排座位中选出k排座位:C[n][k]。
情侣的排列方式:k!。
一对情侣可以互换位置,每队可以选择换或不换:2k。
综上,这一部分的贡献为:C[n][k]2*k!*2k。
接下来考虑n-k对情侣不坐在一起的情况:
不妨设f[x]表示x对情侣不坐在一起的方案数。
首先从2*x个人中选出一个人坐下:2*x。
选一个人和他坐一排且不是他的情侣:2*x-2。
所以,选出两个非情侣的人坐一排方案数:(2*x)*(2*x-2)。
那么接下来有两种情况:
① 这两个人的情侣坐一起:2*(x-1)*f[x-2]。
② 这两个人的情侣不坐一起,那么这两人可视为新的一对情侣:f[x-1]。
综上我们发现f[x]的递推式:f[x]=(2*x)*(2*x-2)*(2*(x-1)*f[x-2]+f[x-1])。
所以最后的ans=C[n][k]2*k!*2k*f[n-k]。
提前预处理:阶乘,阶乘逆元,2的幂,f[]。
#include<bits/stdc++.h> #define RG register #define IL inline #define DB double #define int long long using namespace std; IL int gi() { RG int x=0,w=0; char ch=0; while (ch<'0'||ch>'9') {if (ch=='-') w=1;ch=getchar();} while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar(); return w?-x:x; } const int N=5e6; const int mod=998244353; int n,k,C,G[N+2],pw[N+2],fc[N+2],fcn[N+2]; IL int power(int x,int P) { RG int ans=1; for (;P;P>>=1,x=x*x%mod) if (P&1) ans=ans*x%mod; return ans; } IL void For_pre() { RG int i; for (i=1,fc[0]=1,fcn[0]=1;i<=N;++i) fc[i]=fc[i-1]*i%mod; for (i=1,pw[0]=1;i<=N;++i) pw[i]=(pw[i-1]+pw[i-1])%mod; G[0]=1,G[1]=0,G[2]=16; for (i=3;i<=N;++i) G[i]=(i+i)*(i+i-2)%mod*(G[i-1]+(i+i-2)*G[i-2]%mod)%mod; } signed main () { RG int T=gi(); For_pre(); while (T--) { n=gi(),k=gi(); if (!fcn[k]) fcn[k]=power(fc[k],mod-2); if (!fcn[n-k]) fcn[n-k]=power(fc[n-k],mod-2); C=fc[n]*fcn[k]%mod*fcn[n-k]%mod; printf("%lld ",C*C%mod*fc[k]%mod*pw[k]%mod*G[n-k]%mod); } return 0; }