【BZOJ1004】Cards(HNOI2008)-Burnside引理+DP+逆元
2017-11-25 17:43
381 查看
测试地址:Cards
做法:本题需要用到Burnside引理+DP+逆元。
注意到,按照题目中给的定义,给出的m个置换加上回到自身的置换合在一起是一个大小为m+1的置换群,那么我们可以DP求出对于每个置换的等价类数目,然后使用Burnside引理求出最后答案。至于怎么DP,只要先求出每个置换中各个循环内的元素的个数,然后就可以使用O(n4)的三维背包求出了(这里n的最大值视为20,因为每种牌最多只有20张)。最后要乘上一个1/(m+1),转化成乘上m+1对p的逆元即可。总的时间复杂度为O(mn4)。
以下是本人代码:
做法:本题需要用到Burnside引理+DP+逆元。
注意到,按照题目中给的定义,给出的m个置换加上回到自身的置换合在一起是一个大小为m+1的置换群,那么我们可以DP求出对于每个置换的等价类数目,然后使用Burnside引理求出最后答案。至于怎么DP,只要先求出每个置换中各个循环内的元素的个数,然后就可以使用O(n4)的三维背包求出了(这里n的最大值视为20,因为每种牌最多只有20张)。最后要乘上一个1/(m+1),转化成乘上m+1对p的逆元即可。总的时间复杂度为O(mn4)。
以下是本人代码:
#include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; int a,b,c,m,p,n,x[110]; int f[65][25][25][25],g[65],ans=0; bool vis[65]; int power(int a,int b) { int s=1,ss=a; while(b) { if (b&1) s=(s*ss)%p; b>>=1;ss=(ss*ss)%p; } return s; } void work() { int tot=0; memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) if (!vis[i]) { g[++tot]=0; int now=i; while(!vis[now]) vis[now]=1,g[tot]++,now=x[now]; } memset(f,0,sizeof(f)); f[0][0][0][0]=1; for(int i=1;i<=tot;i++) { for(int sa=0;sa<=a;sa++) for(int sb=0;sb<=b;sb++) for(int sc=0;sc<=c;sc++) { if (sa>=g[i]) f[i][sa][sb][sc]=(f[i][sa][sb][sc]+f[i-1][sa-g[i]][sb][sc])%p; if (sb>=g[i]) f[i][sa][sb][sc]=(f[i][sa][sb][sc]+f[i-1][sa][sb-g[i]][sc])%p; if (sc>=g[i]) f[i][sa][sb][sc]=(f[i][sa][sb][sc]+f[i-1][sa][sb][sc-g[i]])%p; } } ans=(ans+f[tot][a][b][c])%p; } int main() { scanf("%d%d%d%d%d",&a,&b,&c,&m,&p); n=a+b+c; for(int i=1;i<=n;i++) x[i]=i; work(); for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) scanf("%d",&x[j]); work(); } ans=(power(m+1,p-2)*ans)%p; printf("%d",ans); return 0; }
相关文章推荐
- BZOJ 1004 [HNOI2008] Cards
- BZOJ 1004: [HNOI2008]Cards(群论)
- bzoj1004[HNOI2008] Cards
- BZOJ 1004 [HNOI2008]Cards 置换+burnside定理+逆元
- bzoj1004【hnoi2008】Cards
- 【HNOI2008】bzoj1004 Cards
- 【bzoj 1004】[HNOI2008]Cards(burnside 引理)
- bzoj 1004: [HNOI2008]Cards
- [BZOJ1004] [HNOI2008] Cards - 群论,Burnside引理,Polya定理
- [BZOJ1004][HNOI2008]Cards(Burnside引理+dp)
- 【置换群】【bzoj 1004】: [HNOI2008]Cards
- [BZOJ1004][HNOI2008]Cards
- [置换群+背包] BZOJ1004: [HNOI2008]Cards
- bzoj 1004: [HNOI2008]Cards 置换群+dp
- [BZOJ1004](HNOI 2008) Cards
- BZOJ 1004 【HNOI2008】 Cards
- Bzoj1004 [HNOI2008]Cards
- 【BZOJ1004】【HNOI2008】Cards(群论、Burnside引理、背包dp)
- 【BZOJ 1004】【HNOI 2008】Cards
- BZOJ 1004([HNOI2008]Cards-Polya计数+k背包)