洛谷P4921 情侣?给我烧了!(容斥)

传送门
来一发容斥做法。
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=0k(1)i(Cnki)2i!2i(2n2k2i)!(Cnk)22kk!g(n,k)(Cnk)22kk!g(n1,k1)
然后只用预处理出 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;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值