polya计数回顾
来源:互联网 发布:暴力破解rar密码软件 编辑:程序博客网 时间:2024/06/06 02:13
burnside引理
设G={g1,g2...gk},k=|G|, 是[1,n]上的置换群,令c(gi) 表示置换gi 下不动点的个数,那么G将[1,n]划分为等价类>的个数是:l=1|G|∑j=1|G|c(gi)
即是说,等价类个数等于不动点个数的均值。
如果存在gi 将gi(a)−>b 那么我们就说观测到a和b等价。换句话说,我们看到的a和b是同一个东西。polya定理
设G={g1,g2...gk},k=|G|, 是[1,n]上的置换群,令C(gi) 表示置换gi 下循环节的个数,现在用m个颜色对[1,n]着色,那么在G作用下,[1,n]的不同着色方案数为:l=1|G|∑j=1|G|mC(gi) polya定理是burnside的特例。
需要注意的是,burnside算的是[1,n] 这n 个数的不同等价类的个数;polya算的是mn 个方案数中不同等价类的个数。因此,burnside中的[1,n] 是计数对象,而polya中的方案数是计数对象。
burnside中的g 直接作用于计数对象[1,n] ;而polya中的g 虽然也作用于[1,n] ,但[1,n] 不是计数对象,方案数才是,但是g 通过作用到[1,n] 间接作用到方案数上面。两式对比,容易发现mC(gi) 是burnside中的不动点数
比如n=4,g=(123)(4) ,着色方案为f=(abcd), 那么g(f)=(cabd) 。不动点是自己映射到自己,即g(f)=f 。对于上例就是(cabd)=(abcd), 于是有c=a,a=b,b=c,d=d 。因此如果方案f 是g 的不动点,那么在g 的每个循环节内,f 只能染一种颜色。换句话说,用f 染完色后,g 的循环节内的点颜色相同。对于循环节为C(gi) 的置换,其不动点个数为mC(gi)
顺便上一题巩固一下
[HNOI2008]Cards
这里不能直接套用polya,因为每种颜色的使用量是有限制的,因此考虑用burnside计算。对于置换g,因为同一循环节里面只能用同一种颜色,因此我们统计出g的第i个循环节里面有ci个数。然后我们用这些数dp就可以了。
/************************************************************** Problem: 1004 User: 63116021 Language: C++ Result: Accepted Time:120 ms Memory:3616 kb****************************************************************/#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <algorithm>#define clr(A) memset(A,0,sizeof(A))using namespace std;const int MM = 10000;int r,b,g,m,p;int fg = 0;typedef struct GG{ int x,y; GG(int _x,int _y){ x = _x,y = _y; }}G;G Ext_gcd(int a,int b){ if(b==0) return G(1,0); G tmp = Ext_gcd(b,a%b); return G(tmp.y,tmp.x-a/b*tmp.y);}int getcir(int a[],int nn){ int hash[nn+3]; int B[nn+2]; clr(hash); int res = 0; for(int i = 1;i<=nn;i++) if(!hash[i]) { B[++res] = 1; hash[i] = 1; int tmp = a[i]; while(tmp!=i) { hash[tmp] = 1,B[res]++,tmp = a[tmp]; } } int F[res+2][b+2][r+2][g+2]; clr(F); F[0][0][0][0] = 1; for(int i = 1;i<=res;i++) for(int sb = 0;sb<=b;sb++) for(int sr = 0;sr<=r;sr++) for(int sg = 0;sg<=g;sg++) //if(sb+sr+sg>=B[i]) { if(sb>=B[i]) F[i][sb][sr][sg] += F[i-1][sb-B[i]][sr][sg]; if(sr>=B[i]) F[i][sb][sr][sg] += F[i-1][sb][sr-B[i]][sg]; if(sg>=B[i]) F[i][sb][sr][sg] += F[i-1][sb][sr][sg-B[i]]; F[i][sb][sr][sg] %= p; } if(res == nn) fg = 1; return F[res][b][r][g];}int main(){ //freopen("Pr_temp.in","r",stdin); scanf("%d%d%d%d%d",&r,&b,&g,&m,&p); int n = r+b+g; int A[n+2]; int ans = 0; for(int i = 1;i<=m;i++) { for(int j = 1;j<=n;j++) scanf("%d",A+j); ans = (ans+getcir(A,n)) % p; } if(!fg){ for(int i = 1;i<=n;i++) A[i] = i; ans = (ans+getcir(A,n)) % p; m++; } G Gg = Ext_gcd(m,p); int Inv = (Gg.x+p) % p; printf("%d\n",Inv*ans%p); return 0;}
- polya计数回顾
- polya计数回顾
- Polya计数
- Polya计数
- polya计数学习小结
- acm-polya计数公式
- polya计数定理
- poj 2154 polya 计数
- HDU4633(Polya计数)
- hdu 3547(Polya计数)
- hdu 3869 polya计数
- poj 2409 polya计数
- sgu282:Isomorphism(polya计数)
- uva 10294 Polya计数
- Poj2409 polya计数
- poj 2409 【polya计数】
- polya计数模版题总结
- HDU 3441 Rotation(Polya计数)
- 昂贵的聘礼(dij)
- Android面试题汇总
- 多次请求后tomcat网页假死
- 02 bootstrap "modal : is not a function"
- Mac 查看端口占用情况
- polya计数回顾
- 文件路径两种获取方式
- Git使用总结
- Python+Requests抓取中文乱码改进方案
- Android:开源框架xutils介绍之 HttpUtils
- Maven Dependency 丢失
- C++primer学习:类模板(2)类模板:模板参数,成员模板和控制实例化
- H5formData无刷新上传文件
- java中堆和栈的区别