21.7.8 t2

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';
}
posted @ 2021-07-08 16:43  oisdoaiu  阅读(29)  评论(0编辑  收藏  举报