【学习笔记】薛定谔的喵咪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));
}
}