洛谷P4931 情侶?給我燒了!(加強版)(容斥)

傳送門
我們接着這篇題解的思路考慮。
gn,0g_{n,0}到底想表達什麼?
貌似指的是nn個人沒有一對情侶坐在一起的方案數。
emmmmemmmm,那不就是把兩個人綁在一起拿來錯排嗎?
於是我們顯然可以O(n)O(n)預處理這個gg數組了。
先不考慮順序,每次添加一對情侶,只有一個跟前面的人換,另一個不動gi=(2n2)(gi1+gi2)\Rightarrow g_{i}=(2n-2)(g_{i-1}+g_{i-2})
處理完之後對於每一種情況都需要給左側的人標號以及左右的人可以互換gi=i!2i\Rightarrow g_{i}*=i!2^i
搞完了。
代碼:

#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=5e6+5;
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,f[0]=1;
	for(ri n=2,up=5e6;n<=up;++n){
		fac[n]=mul(fac[n-1],n),ifac[n]=mul(ifac[mod-mod/n*n],mod-mod/n);
		f[n]=mul(mul(n-1,2),add(f[n-1],f[n-2]));
	}
	for(ri i=2,up=5e6;i<=up;++i)pw[i]=add(pw[i-1],pw[i-1]),Mul(ifac[i],ifac[i-1]),Mul(f[i],mul(pw[i],fac[i]));
	for(ri k,tt=read();tt;--tt){
		n=read(),k=read();
		cout<<mul(f[n-k],mul(mul(C(n,k),C(n,k)),mul(fac[k],pw[k])))<<'\n';
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章