21.7.8 t2
阿新 • • 發佈:2021-07-08
tag:組合計數
顯然出題人直接把兩個問題直接拼了起來。。
可以列舉放了 \(i\) 個 \(2\),則有 \(n-2i\) 個 \(1\),且序列長度為 \(n-i\)。
然後第二問只與 \(len\) 有關,原問題是先塗色再選點,實際上可以先選點再塗色。選出來的點一定是黑白交錯,而且對應唯一的一種塗色方案。
規定了選擇 \(s\) 個黑點,那麼白點有 \(len-s\) 個,然後規定最後一個一定是白色。
所以就是 \(\binom{len-1}{2(len-s)-1}\)。
#include<bits/stdc++.h> using namespace std; template<typename T> inline void Read(T &n){ char ch; bool flag=false; while(!isdigit(ch=getchar()))if(ch=='-')flag=true; for(n=ch^48;isdigit(ch=getchar());n=(n<<1)+(n<<3)+(ch^48)); if(flag)n=-n; } enum{ MAXN = 10000005, MOD = 998244353 }; inline int ksm(int base, int k=MOD-2){ int res=1; while(k){ if(k&1) res = 1ll*res*base%MOD; base = 1ll*base*base%MOD; k >>= 1; } return res; } int pw1[MAXN], pw2[MAXN]; int n, s, ans; int jc[MAXN<<1], invjc[MAXN<<1]; inline int C(int n, int m){return (n<m or m<0)?0:1ll*jc[n]*invjc[m]%MOD*invjc[n-m]%MOD;} inline int calc(int len){return C(len-1,2*(len-s)-1);} inline void prework(int n){ jc[0] = 1; for(int i=1; i<=n; i++) jc[i] = 1ll*jc[i-1]*i%MOD; invjc[n] = ksm(jc[n]); for(int i=n; i; i--) invjc[i-1] = 1ll*invjc[i]*i%MOD; } int main(){ Read(n); Read(pw1[1]); Read(pw2[1]); Read(s); prework(n<<1); pw1[0] = pw2[0] = 1; for(int i=2; i<=n; i++) pw1[i] = 1ll*pw1[i-1]*pw1[1]%MOD, pw2[i] = 1ll*pw2[i-1]*pw2[1]%MOD; for(int i=0; i<=n/2; i++) // printf("calc(%d) = %d\n",n-i,calc(n-i)), ans = (ans+1ll*calc(n-i)*C(n-i,i)%MOD*pw1[n-2*i]%MOD*pw2[i])%MOD; cout<<ans<<'\n'; }