Luogu4921/4931 情侶?給我燒了! 組合、遞推
阿新 • • 發佈:2019-01-31
stdout shuf freopen amp def 遞推 ack href ace
種方案
4921
4931
第一眼看著就像容斥,但是容斥不怎麽好做……
第二眼想到錯排,結果錯排公式糊上去錯了……
不難考慮到可以先選\(K\)對情侶坐在一起,剩下\(N-K\)對錯排
選\(K\)對情侶坐在一起的方案數是:
選情侶的方案數\(C_N^K \times\)選椅子的方案數\(C_N^K\times\)情侶坐的椅子可以任意排列\(K!\times\)情侶之間可以互換位置\(2^K\)=\((C_N^K)^2K!2^K\)
然後考慮這個錯排
實際上直接糊錯排公式是很難對的,至少我不會直接用錯排公式搞出來……
設\(f_i\)表示\(i\)對情侶錯排的方案數
轉移時枚舉兩個不是情侶的人,有\(2i \times (2i-2)\)
然後考慮TA們的配偶:
①兩個配偶坐在了一起,$f_i \leftarrow 2i \times (2i - 2) \times (i-1) \times 2 \times f_{i-2} $,中間的\(2\)是這兩個配偶可以交換位置
②沒有坐在一起,就相當於一個規模為\(i-1\)的錯排,\(f_i \leftarrow 2i \times (2i-2) \times f_{i-1}\)
預處理階乘、\(2\)的次冪就可以\(O(1)\)回答詢問。
#include<iostream> #include<cstdio> #include<cstdlib> #include<ctime> #include<cctype> #include<algorithm> #include<cstring> #include<iomanip> #include<queue> #include<map> #include<set> #include<bitset> #include<stack> #include<vector> #include<cmath> //This code is written by Itst using namespace std; inline int read(){ int a = 0; char c = getchar(); bool f = 0; while(!isdigit(c) && c != EOF){ if(c == ‘-‘) f = 1; c = getchar(); } if(c == EOF) exit(0); while(isdigit(c)){ a = a * 10 + c - 48; c = getchar(); } return f ? -a : a; } #define int long long const int MOD = 998244353 , MAXN = 5e6 + 9; int shuf[MAXN] , jc[MAXN] , inv[MAXN] , pow2[MAXN]; inline int poww(int a , int b){ int times = 1; while(b){ if(b & 1) times = times * a % MOD; a = a * a % MOD; b >>= 1; } return times; } void init(){ jc[0] = pow2[0] = 1; for(int i = 1 ; i <= 5e6 ; ++i) jc[i] = jc[i - 1] * i % MOD; inv[5000000] = poww(jc[5000000] , MOD - 2); for(int i = 5e6 - 1 ; i >= 0 ; --i) inv[i] = inv[i + 1] * (i + 1) % MOD; for(int i = 1 ; i <= 5e6 ; ++i) pow2[i] = pow2[i - 1] * 2 % MOD; shuf[0] = 1; shuf[1] = 0; for(int i = 2 ; i <= 5e6 ; ++i) shuf[i] = (shuf[i - 1] + 2 * (i - 1) * shuf[i - 2]) % MOD * 2 * i % MOD * (2 * i - 2) % MOD; } signed main(){ #ifndef ONLINE_JUDGE freopen("in","r",stdin); //freopen("out","w",stdout); #endif init(); for(int T = read() ; T ; --T){ int N = read() , Q = read(); printf("%lld\n" , jc[N] * inv[N - Q] % MOD * jc[N] % MOD * inv[Q] % MOD * inv[N - Q] % MOD * pow2[Q] % MOD * shuf[N - Q] % MOD); } return 0; }
Luogu4921/4931 情侶?給我燒了! 組合、遞推