【组合数学】[HNOI2008][HYSBZ/BZOJ1004]Cards
2016-02-02 13:33
489 查看
网上的题解都说用置换,然而我不会,所以,我按照自己的方法写了一份题解。
可以使用多种洗牌法,而每种方法可以使用多次然而输入数据保证任意多次洗牌都可用这 m种洗牌法中的一种代替
说明我们只用考虑仅使用一种洗牌法的情况即可。
然后怎么做呢?搜索?No!
首先,我们考虑一共有多少种染色的方法。
染色时,我们从n(n=Sr+Sb+Sgn=S_r+S_b+S_g)张牌中选SrS_r张染成红色,再从剩下的牌中选SbS_b张染成蓝色,剩下的染成绿色,所以根据乘法原理,总的方案数为S=C(Srn)∗C(Sbn−Sr)∗C(Sgn−Sr−Sb)=C(Srn)∗C(Sbn−Sr)S=C{S_r\choose n}*C{S_b\choose n-S_r}*C{S_g\choose n-S_r-S_b}=C{S_r\choose n}*C{S_b\choose n-S_r}
由于两种染色方法相同当且仅当其中一种可以通过任意的洗牌法洗成另一种
有m种洗牌法,任何一种染色方案都可以根据洗牌法变成其他m种方案,假设这种方案为A。
我们把这m+1中方案看做一组,这一组中的方案通过洗牌能且只能变成其他m种方案,且不会有不属于这一组的方案能通过洗牌变成这一组方案的任何一种。
对于这一组的任何方案,都可以通过洗牌变为A,再变为其他方案,由于输入数据保证任意多次洗牌都可用这 m种洗牌法中的一种代替,所以这一组的方案能通过洗牌变成这一组方案的任何一种。
对于这一组的任何一组方案T,如果能够变为不属于这一组的方案B,那B->T->A,那么B->A,A->B(->是变成的意思),和假设B不属于这一组矛盾。
如果有不属于这一组的方案B能够变为这m+1种方案之一,证明方法同上。
所以,我们的染色方案被重复计算了m+1次。
ans=Sm+1modpans=\frac S{m+1}\mod p
求解S时就不得不mod p了
但是最后一步有除法,怎么办?
乘m+1的逆元就好了,因为p>m+1,且p是质数,所以gcd(m+1,p)=1,由费马小定理可得(m+1)p−1≡1modp(m+1)^{p-1}\equiv1\mod p,所以(m+1)p−2∗(m+1)≡1modp(m+1)^{p-2}*(m+1)\equiv1\mod p,所以m+1的逆元为(m+1)p−2(m+1)^{p-2}
如果你还想看置换的做法,看看【Burnside定理/置换】[HNOI2008][HYSBZ/BZOJ1004]Cards.
题目链接
分析
对题目的分析
题目说可以使用多种洗牌法,而每种方法可以使用多次然而输入数据保证任意多次洗牌都可用这 m种洗牌法中的一种代替
说明我们只用考虑仅使用一种洗牌法的情况即可。
然后怎么做呢?搜索?No!
首先,我们考虑一共有多少种染色的方法。
染色时,我们从n(n=Sr+Sb+Sgn=S_r+S_b+S_g)张牌中选SrS_r张染成红色,再从剩下的牌中选SbS_b张染成蓝色,剩下的染成绿色,所以根据乘法原理,总的方案数为S=C(Srn)∗C(Sbn−Sr)∗C(Sgn−Sr−Sb)=C(Srn)∗C(Sbn−Sr)S=C{S_r\choose n}*C{S_b\choose n-S_r}*C{S_g\choose n-S_r-S_b}=C{S_r\choose n}*C{S_b\choose n-S_r}
由于两种染色方法相同当且仅当其中一种可以通过任意的洗牌法洗成另一种
有m种洗牌法,任何一种染色方案都可以根据洗牌法变成其他m种方案,假设这种方案为A。
我们把这m+1中方案看做一组,这一组中的方案通过洗牌能且只能变成其他m种方案,且不会有不属于这一组的方案能通过洗牌变成这一组方案的任何一种。
Why?
对每种洗牌法,都存在一种洗牌法使得能回到原状态。对于这一组的任何方案,都可以通过洗牌变为A,再变为其他方案,由于输入数据保证任意多次洗牌都可用这 m种洗牌法中的一种代替,所以这一组的方案能通过洗牌变成这一组方案的任何一种。
对于这一组的任何一组方案T,如果能够变为不属于这一组的方案B,那B->T->A,那么B->A,A->B(->是变成的意思),和假设B不属于这一组矛盾。
如果有不属于这一组的方案B能够变为这m+1种方案之一,证明方法同上。
所以,我们的染色方案被重复计算了m+1次。
ans=Sm+1modpans=\frac S{m+1}\mod p
One more thing
求解组合数的过程中,可以用longlong存储。求解S时就不得不mod p了
但是最后一步有除法,怎么办?
乘m+1的逆元就好了,因为p>m+1,且p是质数,所以gcd(m+1,p)=1,由费马小定理可得(m+1)p−1≡1modp(m+1)^{p-1}\equiv1\mod p,所以(m+1)p−2∗(m+1)≡1modp(m+1)^{p-2}*(m+1)\equiv1\mod p,所以m+1的逆元为(m+1)p−2(m+1)^{p-2}
代码
[code]#include<cstdio> int sr,sg,sb,m,p,ans=1,n; void Read(int &x){ char c; while(c=getchar(),c!=EOF) if(c>='0'&&c<='9'){ x=c-'0'; while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0'; ungetc(c,stdin); return; } } int quick_pow(int a,int b){ int ret=1; while(b){ if(b&1) ret=ret*a%p; a=a*a%p; b>>=1; } return ret; } int main() { Read(sr),Read(sb),Read(sg),Read(m),Read(p); n=sr+sb+sg; int i; long long t; for(t=i=1;i<=sr;i++) t=t*(n-i+1)/i; ans=ans*(t%p)%p; n-=sr; for(t=i=1;i<=sg;i++) t=t*(n-i+1)/i; ans=ans*(t%p)%p; ans=(ans*quick_pow(m+1,p-2))%p; printf("%d",ans); }
如果你还想看置换的做法,看看【Burnside定理/置换】[HNOI2008][HYSBZ/BZOJ1004]Cards.
相关文章推荐
- SparkContext的parallelize的参数
- IOS开发之异步加载网络图片并缓存本地实现瀑布流(一)
- Security5:Execute AS 和 impersonate 权限
- H5 新属性
- 3389肉鸡快捷键
- 追女孩啥时候该表白
- js日期操作
- (总结)andorid 自定义View
- What is a fully qualified domain name (FQDN)?
- Cannot create TypedQuery for query with more than one return using requested result type
- 关于TNS_ADMIN环境变量
- Pycharm编码问题导致django UnicodeDecodeError 报错
- 应用被强杀了怎么办
- 聊聊高并发(二十五)解析java.util.concurrent各个组件(七) 理解Semaphore
- Codeforces Round #338 (Div. 2)
- Linux 常用命令
- perl 微信取自己的ID
- linux/ubuntu取消sudo输入密码的办法
- CentOS 系统配置完jdk,tomcat mysql,nginx 项目发布步骤
- php HTML安全过滤