1 条题解

  • 0
    @ 2025-8-24 22:21:55

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar duyi
    大家好我是于之航爸爸

    搬运于2025-08-24 22:21:55,当前版本为作者最后更新于2020-07-16 18:19:01,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    来呀,快活呀↓

    超超超超超爽的阅读体验

    题目大意

    给定三个正整数mm, aa, bb。要求在[1,2m][1,2m]中选出aa个奇数,bb个偶数,并且选出的数两两不相邻。问有多少种选择的方案。方案数对998244353998244353取模。

    TT组测试数据。

    数据范围:1a,bm1061\leq a,b\leq m\leq 10^6a+bma+b\leq m1T1061\leq T\leq 10^6

    本题题解

    考虑相邻的一奇一偶,也就是形式化地表述为2i+12i+1, 2i+22i+2 (0i<m0\leq i<m)这两个数,它们不可能同时被选中。对于第ii组数,如果2i+12i+1(奇数)被选中,称这一组为A\text{A};如果2i+22i+2(偶数)被选中,称这一组为B\text{B};如果都没有被选中,称这一组为C\text{C}。则任何一种合法的选择方案,可以被表示为一个长度为mmABC\text{ABC}串,其中有aaA\text{A}bbB\text{B},和mabm-a-bC\text{C},并且不允许出现BA\text{BA}这个子串。我们相当于要求这样的ABC\text{ABC}串的数量。

    先不考虑A\text{A}B\text{B}C\text{C}的相对位置关系可以任意安排,它们共有b+(mab)=mab+(m-a-b)=m-a个,所以任意安排的方案数是(mab){m-a\choose b}

    再插入A\text{A}A\text{A}不能被插入在B\text{B}后面,除此之外其他任何位置都是可以的。考虑第11A\text{A},它可以被插入在最前面,或者某个C\text{C}后面,所以有mab+1m-a-b+1种方案;第22A\text{A},除了最前面和某个C\text{C}后面以外,还能插入在第11A\text{A}后面,所以有mab+2m-a-b+2种方案;以此类推,第kkA\text{A}mab+km-a-b+k种插入方案。同时,所有A\text{A}是本质相同的,所以还要除以a!a!。所以插入A\text{A}的总方案数就是:$\frac{(m-a-b+1)\cdot(m-a-b+2)\cdots(m-a-b+a)}{a!}={m-b\choose a}$。

    因此答案就是:(mab)(mba){m-a\choose b}\cdot{m-b\choose a}

    TT次求组合数。预处理阶乘和阶乘的逆元即可。

    时间复杂度O(m+T)O(m+T)

    参考代码(本代码仅供参考,建议添加读入优化):

    //problem:P6561
    #include <bits/stdc++.h>
    using namespace std;
    
    #define pb push_back
    #define mk make_pair
    #define lob lower_bound
    #define upb upper_bound
    #define fi first
    #define se second
    #define SZ(x) ((int)(x).size())
    
    typedef unsigned int uint;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> pii;
    
    template<typename T>inline void ckmax(T& x,T y){x=(y>x?y:x);}
    template<typename T>inline void ckmin(T& x,T y){x=(y<x?y:x);}
    
    const int MAXN=2e6;
    const int MOD=998244353;
    inline int mod1(int x){return x<MOD?x:x-MOD;}
    inline int mod2(int x){return x<0?x+MOD:x;}
    inline void add(int& x,int y){x=mod1(x+y);}
    inline void sub(int& x,int y){x=mod2(x-y);}
    inline int pow_mod(int x,int i){int y=1;while(i){if(i&1)y=(ll)y*x%MOD;x=(ll)x*x%MOD;i>>=1;}return y;}
    
    int fac[MAXN+5],ifac[MAXN+5];
    inline int comb(int n,int k){
    	if(n<k)return 0;
    	return (ll)fac[n]*ifac[k]%MOD*ifac[n-k]%MOD;
    }
    void facinit(int lim=MAXN){
    	fac[0]=1;
    	for(int i=1;i<=lim;++i)fac[i]=(ll)fac[i-1]*i%MOD;
    	ifac[lim]=pow_mod(fac[lim],MOD-2);
    	for(int i=lim-1;i>=0;--i)ifac[i]=(ll)ifac[i+1]*(i+1)%MOD;
    }
    
    int m,a,b;
    int main() {
    	facinit();
    	int T;cin>>T;while(T--){
    		cin>>m>>a>>b;
    		int ans = (ll)comb(m-a,b) * comb(m-b,a) % MOD;
    		cout<<ans<<endl;
    	}
    	return 0;
    }
    
    • 1

    信息

    ID
    5255
    时间
    1000ms
    内存
    125MiB
    难度
    5
    标签
    (无)
    递交数
    0
    已通过
    0
    上传者