博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 1004: [HNOI2008]Cards
阅读量:4578 次
发布时间:2019-06-08

本文共 1365 字,大约阅读时间需要 4 分钟。

注意题目的条件: "输入数据保证任意多次洗牌都可用这 m种洗牌法中的一种代

替"

所以对于每种方案,只要考虑经过一次洗牌后可能变成的情况

显然,如果有 m 种洗牌法,那么一种方案就可以被洗出 m+1 种方案

继续考虑,如果有另一种方案不属于这 m+1 种方案

那么它一定也可以洗出另外不重复的 m+1 种方案

所以推广一下,如果不考虑洗牌时方案有 sum 种,那么最后答案就是 $\frac{sum}{m+1}$

然后考虑如何求 sum

设 $n=S_r+S_b+S_g$

红色可以在 n 张空白牌中随便选,所以有 $C^{S_r}_{n}$ 种选法

然后考虑蓝色,因为红色已经选了,所以只能在 $n-S_r$ 中随便选,有 $C^{S_b}_{n-S_r}$ 种选

最后绿色没得选了,只能把剩下的全染成绿色,有1种选法

乘起来,化简一波,得到$\frac{(S_r+S_b+S_g)!}{(S_r!\cdot S_b!\cdot S_g!)}$

最后答案再除以 $(m+1)$ 就好了

注意有取余,所以除要乘逆元

直接费马小定理就好了,代码就不注释了

 

#include
#include
#include
#include
#include
using namespace std;inline int read(){ int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f;}int sa,sb,sc,m,mo;inline int ksm(int x,int y){ int res=1; while(y) { if(y&1) res=res*x%mo; x=x*x%mo; y>>=1; } return res;}int f[107];int main(){ sa=read(); sb=read(); sc=read(); m=read(); mo=read(); int a; for(int i=1;i<=m;i++) for(int i=1;i<=sa+sb+sc;i++) a=read(); f[0]=1; for(int i=1;i<=sa+sb+sc;i++) f[i]=f[i-1]*i%mo; printf("%d",f[sa+sb+sc]*ksm(f[sa]*f[sb]%mo*f[sc]%mo*(m+1)%mo,mo-2)%mo); return 0;}

 

转载于:https://www.cnblogs.com/LLTYYC/p/10103163.html

你可能感兴趣的文章
UITableViewCell背景色.选中背景色,分割线,字体颜色设置
查看>>
MyBatis笔记一:GettingStart
查看>>
查找不同的木棍
查看>>
面试题:顺时针打印矩阵
查看>>
DataSet、DataTable、DataRow、DataColumn区别及使用实例
查看>>
python 特殊方法
查看>>
Python3 练习笔记四
查看>>
装箱问题
查看>>
Android线程管理(一)——线程通信
查看>>
vim 使用技巧
查看>>
Periodic String UVa1225
查看>>
Android 演示 DownloadManager——Android 下载 apk 包并安装
查看>>
采用oracle存储过程读取excel文件更新表
查看>>
固定虚拟机中windows系统的ip地址
查看>>
【转】正则应用实例,如将多个空格改为1个空格
查看>>
移动端自动打包平台
查看>>
gradle 使用总结
查看>>
C#函数式程序设计初探——重构应用篇
查看>>
兼容的获取选择文本方法
查看>>
谈一谈git和SVN两大版本管理工具。
查看>>