【学习笔记】薛定谔的喵咪Cat—球盒问题(全详解)

【学习笔记】薛定谔的喵咪Cat—球盒问题(全详解)

【题目描述】

当一个猫在盒子里时,因为放射物的状态我们不知道,所以猫的状态我们也不知道,这就所谓猫的生死纠缠态,也是所谓的薛定谔的猫。

当我们做需要大量实验时,就需要统计猫的个数与盒子的数量,以及之间的关系。因为实验情况不同,所以我们要研究的模型也不尽相同。我们用 \(opt\) 表示。

\(opt = 1:\) 猫的颜色不同,盒子的颜色不同允许盒子为空。

\(opt = 2:\) 猫的颜色相同,盒子的颜色不同不许盒子为空。

\(opt = 3:\) 猫的颜色相同,盒子的颜色不同允许盒子为空。

\(opt = 4:\) 猫的颜色不同,盒子的颜色相同不许盒子为空。

\(opt = 5:\) 猫的颜色不同,盒子的颜色不同不许盒子为空。

\(opt = 6:\) 猫的颜色不同,盒子的颜色相同允许盒子为空。

\(opt = 7:\) 猫的颜色相同,盒子的颜色相同允许盒子为空。

\(opt = 8:\) 猫的颜色相同,盒子的颜色相同不许盒子为空。

\(opt = 9:\) 此时猫分两种颜色,黑色和白色分别各有 \(a\) 只,盒子数量和猫的个数相同,每个盒子里面只能放一只猫,并且必须满足如下限制,即每一个白色猫必须和一只黑色猫配对(白猫在黑猫前,允许嵌套)。
\(eg.\) 我们用 \(0\) 表示白猫,\(1\) 表示黑猫,则:
\(0011\)\(010101\)\(001011\) 合法。
\(1100\)\(101010\)\(010110\) 不合法。

注:某物有色代表此物每一个都不相同

给定 \(opt\),猫的数量 \(a\),盒子的数量 \(b\),将猫放入盒子,求所有本质不同的合法方案数。

【输入】

第一行包含一个整数 \(q\) 表示询问的个数,接下来 \(q\) 行,每行包含三个整数 \(opt,a,b\),分别表示当前询问的是模型 \(opt\),其中猫为 \(a\) 个,盒子为 \(b\) 个。

【输出】

输出包含 \(q\) 行,每行一个整数表示询问的答案,要求答案对 \(998244353\) 取模。

【样例】

样例输入:
9
1 3 2
2 3 2
3 3 2
4 3 2
5 3 2
6 3 2
7 3 2
8 3 2
9 3 6

样例输出:
8
2
4
3
6
4
2
1
5

【数据范围】

测试点 \(q\) \(a,b\) 包含 \(opt\)
\(1\) \(q \leqslant 5\) \(a,b \leqslant 5\) \(1\)
\(2\) \(q \leqslant 10\) \(a,b \leqslant 10\) \(1,2\)
\(3\) \(q \leqslant 15\) \(a,b \leqslant 10^6\) \(1,2,3\)
\(4\) \(q \leqslant 20\) \(a,b \leqslant 100\) \(1,2,3,4\)
\(5\) \(q \leqslant 25\) \(a,b \leqslant 100\) \(1,2,3,4,5\)
\(6\) \(q \leqslant 30\) \(a,b \leqslant 100\) \(1,2,3,4,5,6\)
\(7\) \(q \leqslant 35\) \(a,b \leqslant 100\) \(7,8\)
\(8\) \(q \leqslant 40\) \(a,b \leqslant 10^6\) \(9\)
\(9\) \(q \leqslant 45\) \(a,b \leqslant 100\) \(7,8,9\)
\(10\) \(q \leqslant 50\) \(a,b \leqslant 100\) \(1,2,3,4,5,6,7,8,9\)

【分析】

\(a\) 只喵咪放入 \(b\) 个盒子,其实就是总共 \(8\) 种球盒模型混进去了一个不明物体QAQ。

模型 球是否有色 盒是否有色 盒可否为空 计算公式
\(1\) \(b^a\) 快速幂
\(2\) × × \(C_{a-1}^{b-1}\) 组合数
\(3\) × \(C_{a+b-1}^{b-1}\) 组合数(或\(C_{a+b-1}^a\)
\(4\) × × \(S_2(a,b)\) 第二类斯特林数
\(5\) × \(b!*S_2(a,b)\) 第二类斯特林数
\(6\) × \(B_a\) 贝尔数(或\(\sum_{i=1}^bS_2(a,i)\)
\(7\) × × \(dp[a+b][b]\) \(dp[i][j]=dp[i-j][j]+dp[i-1][j-1]\)
\(8\) × × × \(dp[a][b]\) \(dp[i][j]=dp[i-j][j]+dp[i-1][j-1]\)

接下来将会以 \(“\) 喵咪 \(”\) 指代 \(“\) \(”\) 作解释。

1:快速幂

问题描述: 球有色,盒子有色,盒子可为空。\((a,b \leqslant 10^6)\)

这个应该是最简单的了。对于每一个喵咪都可以任意的安排在任意一个盒子里面,于是每只喵咪都有 \(b\) 种选择,一共 \(a\) 只喵咪。

得出答案为:\(b^a\)

2:组合数

问题描述: 球无色,盒子有色,盒子不可为空。\((a,b \leqslant 10^6)\)

既然喵咪都长一个样,那就把它们排成一排站好,在其之间插入 \(b-1\) 个挡板,将其分为 \(b\) 个部分,每个部分都有若干只喵咪,而\(a\) 只喵咪之间一共有 \(a-1\) 个空隙可插。

得出答案为: \(C_{a-1}^{b-1}\)

3:组合数

问题描述: 球无色,盒子有色,盒子可为空。\((a,b \leqslant 10^6)\)

在上述模型 \(2\) 的基础上稍作改进即可。

盒子不可为空,这说明了什么?\(a\) 只喵咪之间的一共 \(a+1\) 个空位置里面(对于这道题,喵咪队列的外面也可以插了),每个位置都可插无限个挡板(实际上最大值为 \(b-1\) 个),也就是说板子插到哪儿,同时插几根板子,都没有限制。

既然没有那么多要求,那就干脆把喵咪和板子都看作同一类元素,插进去后的状态就是这一共 \(a+b-1\) 个元素的某种排列,要求是这个排列中板子的个数为 \(b-1\)(或者说喵咪的个数为 \(a\))。

得出答案为:\(C_{a+b-1}^{b-1}\)(或\(C_{a+b-1}^a\)) 。

4:第二类斯特林数

问题描述: 球有色,盒子无色,盒子不可为空。\((a,b \leqslant 100)\)

这里的喵咪有颜色分别,也就是说每只喵咪都不相同,而盒子又都是没有区别的,那么就可以考虑将其视作集合。将盒子视为集合,喵咪视为里面的元素,恰好满足集合的定义。再看看 \(Stirling\) 数的定义:\(S_2(a,b)\) 表示将 \(a\)个不同的元素拆分成 \(b\) 个集合的方案数。于是这个问题就这样解决啦!

得出答案为:\(S_2(a,b)\)

5:第二类斯特林数

问题描述: 球有色,盒子有色,盒子不可为空。\((a,b \leqslant 100)\)

盒子与球 \([P1287]\)总算是找到一道例题了。。。。

在上述模型 \(4\) 的基础上稍作改进即可。

由于集合出现了颜色分别,因此对于每一种元素(喵咪们)的划分,都可以有 \(b!\) 种方案提供集合来装下这些元素。

得出答案为:\(b!*S_2(a,b)\)

6:贝尔数

问题描述: 球有色,盒子无色,盒子可为空。\((a,b \leqslant 100)\)

在上述模型 \(4\) 的基础上稍作改进即可。

盒子可以为空,说明划分出来的集合数目可以是任意的(当然要小于等于 \(b\) 啦QAQ),为什么呢?假如我们划分出了 \(5\) 个集合来装元素,那么剩下的 \(b-5\) 个作为空集就可以了。由于本题数据不大(\(a,b \leqslant 100\)),直接暴力枚举划分 \(1\)~\(b\) 个集合的方案数再求和就 \(ok\) 啦。

实际上就是贝尔数。

得出答案为:\(B_a=\sum_{i=1}^bS_2(a,i)\)

7 , 8:递推

关于 \(7\)\(8\) 似乎有一个极其复杂数学公式推导,奈何本人能力有限,无法理解,只会递推方程解决。

先说 \(8\),再说 \(7\)

模型8

问题描述: 球无色,盒子无色,盒子不可为空。\((a,b \leqslant 100)\)

\(dp[i][j]\) 表示 \(i\) 只喵咪和 \(j\) 个盒子的方案数。

问题可理解为:求关于 \(x_{1,2,3...b}\) 的方程 \(\sum_{i=1}^b x_i=a\) \((\)为了避免方案重复:\(1 \leqslant x_1 \leqslant x_2 ... \leqslant x_b)\) 的解的个数。

这里可以分两种情况:

\((1).\) \(x_1=1\)
原方程可化为:\(\sum_{i=2}^b x_i=a-1\) \((1 \leqslant x_2 \leqslant x_3 ... \leqslant x_b)\)
即:\(\sum_{i=1}^{b-1} x'_i=a-1\) \((1 \leqslant x'_1 \leqslant x'_2 ... \leqslant x'_{b-1})\)
其方案数为 \(dp[a-1][b-1]\)

\((2).\) \(x_1 \geqslant 2\)
原方程可化为:\(\sum_{i=1}^b (x_i-1)=a-b\) \((2 \leqslant x_1 \leqslant x_2 ... \leqslant x_b)\)
\(\sum_{i=1}^b x'_i=a-b\) \((1 \leqslant x'_1 \leqslant x'_2 ... \leqslant x'_b)\)
其方案数为 \(dp[a-b][b]\)

综上所述,递推方程为:\(dp[a][b]=dp[a-1][b-1]+dp[a-b][b]\)

得出答案为: \(dp[a][b]\)

模型7

问题描述: 球无色,盒子无色,盒子可为空。\((a,b \leqslant 100)\)

在上述模型 \(8\) 的基础上稍作改进即可。

盒子可以为空就意味着多了一种情况:\(x_?=0\),可以在方程两边同时加上一个 \(b\),原方程可化为:\(\sum_{i=1}^b (x_i+1)=a+b\) \((0 \leqslant x_1 \leqslant x_2 ... \leqslant x_b)\)

问题可转化为:求关于 \(x'_{1,2,3...b}\) 的方程 \(\sum_{i=1}^b x'_i=a+b\) \((1 \leqslant x'_1 \leqslant x'_2 ... \leqslant x'_b)\)的解的个数。和模型 \(8\) 里那个问题一样,只是这里的答案要变一下 。

得出答案为:\(dp[a+b][b]\)

9:Catalan数

(部分摘自百度百科以及\(Silent\)_\(EAG\))

问题描述: 此时猫分两种颜色,黑色和白色分别各有 \(a\) 只,盒子数量和猫的个数相同,每个盒子里面只能放一只猫,并且必须满足如下限制,即每一个白色猫必须和一只黑色猫配对(白猫在黑猫前,允许嵌套)。\((a,b \leqslant 10^6)\)

\(eg.\) 我们用 \(0\) 表示白猫,\(1\) 表示黑猫,则:
\(0011\)\(010101\)\(001011\) 合法。
\(1100\)\(101010\)\(010110\) 不合法。

实际上这已经不能算是球盒模型的问题了,只是 \(Catalan\) 的一种变型而已。

当时这道题作为一道 \(noip\) 考前模拟的压轴题,是一个学长自己出的,后来他告诉我们:正规考式的压轴题一般都是这种按子问题得分的形式,而且为了防 \(AK\) 会把最后一问设置地极其反人类,当时我就懵逼了。。。现在想想好像难度也不是太高,只要对 \(Catalan\) 熟悉,看一眼就知道是简单套路,或者直接打个表也能看出来 \((\) \(Catalan\) 数的前几项: \(1,1,2,4,14,42,132)\)

关于这个问题的 \(6\) 种变型

(1). 火车进出栈

一个栈的进栈序列为 \(1,2,3,..n,\) 有多少个不同的出栈序列?

(2). 找零钱(找一半)

\(2n\) 个人排成一行进入剧场。入场费 \(5\) 元。其中只有 \(n\) 个人有一张 \(5\) 元钞票,另外 \(n\) 人只有 \(10\) 元钞票,剧院无其它钞票,问有多少中方法使得只要有 \(10\) 元的人买票,售票处就有 \(5\) 元的钞票找零?

(3). 三角网格


形如这样的直角三角形网格,从左上角开始,只能向右走和向下走,问总共有多少种走法?

(4). 括号排列

\(n\) 对括号,可以并列或嵌套排列,共有多少种情况?

(5). 球盒问题

见上。

(6). 最适合理解的模型

\(n\)\(0\)\(n\)\(1\) 组成一个 \(2n\) 位的 \(2\) 进制数,要求从左到右扫描时,\(1\) 的累计数始终都小于等于 \(0\) 的累计数,求满足条件的数有多少?

理解方式

模型
\((1)\) 入栈 出栈
\((2)\) \(5\) 元支付 \(10\) 元支付
\((3)\) 向下走 向右走
\((4)\) 左括号 右括号
\((5)\) \(0\) \(1\)
\((6)\) \(0\) \(1\)
注:同列事件可视为等价,且在题目要求中左边事件的次数/大小需要始终大于右边

观察模型 \((6)\):在 \(2n\) 位上填入 \(n\)\(0\) 的方案数为 \(C_{2n}^n\)。而从 \(C_{2n}^n\) 中减去不符合要求的方案数即为所求答案。

在从左往右扫时,必然会在某一个奇数位 \(2p+1\) 上首先出现 \(p+1\)\(1\),和 \(p\)\(0\)

此后的 \([2p+2,2n]\) 上的 \(2n−(2p+1)\) 位有 \(n−p\)\(0\) , \(n−p−1\)\(1\)。如若把后面这部分 \(2n−(2p+1)\) 位的 \(1\)\(0\) 互换,使之成为 \(n−p\)\(1\)\(n−p−1\)\(0\),结果得 \(1\) 个由 \(n+1\)\(1\)\(n−1\)\(0\) 组成的 \(2n\) 位数,即一个不合法的方案必定对应着一个由 \(n+1\)\(1\)\(n-1\)\(0\) 组成的一个排列

还可以倒过来反证:

任意一个由 \(n+1\)\(1\)\(n-1\)\(0\) 组成的一个排列,由于 \(1\) 的个数多了 \(2\) 个,且 \(2n\) 为偶数,所以必定在某个奇数位 \(2p+1\) 上出现 \(1\) 的个数超过 \(0\) 的个数。同样把后面部分 \(1\)\(0\) 互换,成为了由 \(n\)\(0\)\(n\)\(1\) 组成的 \(2n\) 位数。

由此,每一个不合法的方案总是与唯一一个\(n+1\)\(1\)\(n−1\)\(0\) 组成的排列一一对应。

于是,不合法的方案数就可以写作:\(C_{2n}^{n+1}\),得出答案为: \(Catalan(n)=C_{2n}^n-C_{2n}^{n+1}\)

可以将这个式子再化简一下:

\(\begin{aligned} \text Catalan(n) &=C_{2 n}^{n}-C_{2 n}^{n+1} \\ &=\frac{(2 n) !}{n ! n !}-\frac{(2 n)}{(n+1) !(n-1) !} \\ &=\frac{(2 n) !}{\frac{n+1}{n+1} * n(n-1) !}-\frac{(2 n) !}{(n+1) !(n-1) !} \\ &=\frac{(2 n) !}{(n+1) ! *(n-1) !} *\left(\frac{n+1}{n}-1\right) \\ &=\frac{(2 n) !}{(n+1) n ! *(n-1) !} * \frac{1}{n} \\ &=\frac{(2 n) !}{(n+1) n ! * \frac{n !}{n+1}} \\ &=\frac{C_{2 n}^{n}}{n+1} \end{aligned}\)

【Code】

#include<cstdio>
#define LL long long
#define Re register LL
const int P=998244353,N=1e6+5;
LL T,a,b,f,opt,cnt,jc[N*2+5],dp[205][205],S[105][105];
inline void in(Re &x){
    x=f=0;char c=getchar();
    while(c<'0'||c>'9')f|=c=='-',c=getchar();
    while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
    if(f)x=-x;
}
inline LL mi(Re x,Re k){
    Re ans=1;
    while(k){
        if(k&1)ans=(ans*x)%P;
        x=(x*x)%P;k>>=1;
    }
    return ans%P;
} 
inline LL niv(Re x){return mi(x,P-2);}
inline LL c(Re m,Re n){
    if(n<m)return 0;
    if(n<P)return jc[n]*niv(jc[m])%P*niv(jc[n-m])%P;
    return c(m/P,n/P)*c(m%P,n%P)%P;
}
inline void Stirling(){
    for(Re i=0;i<=100;++i)S[i][i]=1;
    for(Re i=1;i<=100;++i)
    	for(Re j=1;j<=100;++j)
            S[i][j]=(S[i-1][j-1]+S[i-1][j]*j%P)%P;
}
inline void DP(){
    dp[0][0]=1;
    for(Re i=1;i<=200;++i)
    	for(Re j=1;j<=i;++j)
            dp[i][j]=(dp[i-j][j]+dp[i-1][j-1])%P;
}
inline LL Catalan(Re n){return c(n,n<<1)*niv(n+1)%P;}
int main(){
//  freopen("cat.in","r",stdin);
//  freopen("cat.out","w",stdout);
    jc[0]=1;for(Re i=1;i<=N*2;i++)jc[i]=jc[i-1]*i%P;
    in(T);Stirling();DP();
    while(T--){
        in(opt),in(a),in(b);
        if(opt==1)printf("%lld\n",mi(b,a));
        else if(opt==2)printf("%lld\n",c(b-1,a-1));
        else if(opt==3)printf("%lld\n",c(b-1,a+b-1));
        else if(opt==4)printf("%lld\n",S[a][b]);
        else if(opt==5)printf("%lld\n",jc[b]*S[a][b]%P);
        else if(opt==6){
            Re ans=0;
            for(Re i=1;i<=b;++i)(ans+=S[a][i])%=P;
            printf("%lld\n",ans);
        }
        else if(opt==7)printf("%lld\n",dp[a+b][b]);
        else if(opt==8)printf("%lld\n",dp[a][b]);
        else if(opt==9)printf("%lld\n",Catalan(a));
    }
}
posted @ 2019-07-12 16:38  辰星凌  阅读(1287)  评论(0编辑  收藏  举报