【HNOI2008】Cards
2017-12-26 15:34
113 查看
题意
有n张牌,可以染成红,蓝,绿三种颜色,并且每种颜色的牌的数目有规定,分别为sr,sb,sg(保证sr+sb+sg=n)
同时有m+1个置换(m洗牌方法+不洗牌),两种染色方案不同当且仅当这两方案不能通过m+1个置换变成一样
问染色方案模p的余数
n≤60,m<p≤100,max{sr,sb,sg}≤20,p为质数
解法
很容易得到Ans=总方案数重复度
总方案数很容易求,Tot=Csrn∗Csbn−sr∗Csgn−sr−sb
至于求重复度,考虑到每一种方案都可以通过m种置换变成m种方案,加上自己就是m+1种,所以直接乘以m+1的逆元即可
复杂度
O(n+logp)
代码
有n张牌,可以染成红,蓝,绿三种颜色,并且每种颜色的牌的数目有规定,分别为sr,sb,sg(保证sr+sb+sg=n)
同时有m+1个置换(m洗牌方法+不洗牌),两种染色方案不同当且仅当这两方案不能通过m+1个置换变成一样
问染色方案模p的余数
n≤60,m<p≤100,max{sr,sb,sg}≤20,p为质数
解法
很容易得到Ans=总方案数重复度
总方案数很容易求,Tot=Csrn∗Csbn−sr∗Csgn−sr−sb
至于求重复度,考虑到每一种方案都可以通过m种置换变成m种方案,加上自己就是m+1种,所以直接乘以m+1的逆元即可
复杂度
O(n+logp)
代码
#include<iostream> #include<cstdlib> #include<cstdio> #define Rint register int #define Lint long long int using namespace std; int n,sr,sb,sg,m,p; int fac[100],ans; int pow(int x) { int ret=1,k=p-2; while( k ) { if( k&1 ) ret=ret*x%p; x=x*x%p,k/=2; } return ret; } int C(int n,int m) { return fac *pow( fac[m] )%p*pow( fac[n-m] )%p; } int main() { scanf("%d%d%d%d%d",&sr,&sb,&sg,&m,&p); n=sr+sb+sg,fac[0]=1; for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%p; ans=C( n,sr )*C( n-sr,sb )%p*C( n-sr-sb,sg )%p*pow( m+1 )%p; printf("%d\n",ans%p); return 0; }
相关文章推荐
- bzoj1004 [HNOI2008]Cards【Burnside/Polya】
- 【bzoj1004】[HNOI2008]Cards burnside引理+dp
- 【BZOJ 1004】 [HNOI2008]Cards
- [BZOJ1004] [HNOI2008] Cards - 群论,Burnside引理,Polya定理
- Bzoj1004 [HNOI2008]Cards
- [BZOJ1004][HNOI2008]Cards(置换群+背包+乘法逆元)
- 【BZOJ】1004: [HNOI2008]Cards(置换群+polya+burnside)
- 【BZOJ 1004】 [HNOI2008]Cards 【burnside引理】
- [HNOI2008]Cards
- BZOJ_1004_[HNOI2008]Cards_burnside+DP
- 【Burnside定理/置换】[HNOI2008][HYSBZ/BZOJ1004]Cards
- [HNOI2008]Cards
- bzoj1004: [HNOI2008]Cards
- [bzoj 1004][HNOI 2008]Cards(Burnside引理+DP)
- bzoj1004 [HNOI2008]Cards
- luogu P1446 [HNOI2008]Cards
- Burnside引理和Polya定理 & [bzoj 1004] [HNOI2008]Cards:Burnside引理,动态规划
- 【组合数学】[HNOI2008][HYSBZ/BZOJ1004]Cards
- [BZOJ1004][HNOI2008]Cards
- 【BZOJ1004】Cards(HNOI2008)-Burnside引理+DP+逆元