【群论】polya定理

对Polya定理的个人认识

    我们先来看一道经典题目:

    He‘s Circles(SGU 294)

        有一个长度为N的环,上面写着“X”和“E”,问本质不同的环有多少个(不能旋转重复就称之为本质不同)

输入样例:4

输出样例:6

那么要怎么办呢?暴力显然暴不出来……

我们可以考虑使用置换群。

我们有两种算法:

①Burnside引理:

答案直接为1/|G|*(D(a1)+D(a2)+D(a3)+……+D(as))

其中D(ak)为在进行置换群置换操作ak下不变的元素的个数。

在N=4下一共有四个置换群:

(1 2 3 4    (1 2 3 4    (1 2 3 4    (1 2 3 4

1 2 3 4)    2 3 4 1)    3 4 1 2)    4 1 2 3)

那么显然在置换a1下都不变,那么D(a1)=16 (4*4)

EEEE和XXXX在置换a2下都不变,所以D(a2)=2

XXXX和EEEE还有XEXE以及EXEX在置换a3下都不变,所以D(a3)=4

XXXX和EEEE在置换a4的情况下都不变,D(a4)=2

最后根据公式计算出1/|4|*(16+2+4+2)=6(种)

 

        ②Polya定理

             回顾上面的Burnside算法,是否感觉D不太好实现呢?

那么我们就可以用一种更容易理解、适应力强、时间复杂度低、编程复杂度低的方法就是群论的最厉害的Polya定理

其实Polya定理与Burnside引理本质上的区别并不是很大,只不过入手问题的角度不一样。

我们可以发现,一个循环节之间的“不变元素”可以互相交换从而不影响整体,所以我们可以设Ci为置换群i的循环节个数。

例如(1 2 3 4 5

3 5 1 4 2)

的循环节就为:1和3循环1->3->1……

2和5循环2->5->2……

4和它自身循环4->4->4……

那么循环节数就为3

再回来看现在这个题目,我们可以抽象地把Ci替换掉Di

那么Di=p^C(i) (p为总共的字母数)

相同循环节中的元素可以互相置换,所以Di=p^C(i)

polya公式为1/|G|(p^C(1)+p^C(2)+……+p^C(s))

以4为例,则1/|G|=1/4

C(1):循环节为(1)(2)(3)(4),所以C(1)=4

C(2):循环节为(4 3 2 1),所以C(2)=1

C(3):循环节为(1 3)(2 4),所以C(3)=2

C(4):循环节为(1 2 3 4),所以C(4)=1

那么答案就为1/4(2^4+2^1+2^2+2^1)=6

这里的C相对于上面的D来说要简单,记得XJR学长给我讲过环的判定,直接任选一个没有选过的点,从这个点开始映射,走过的点标上1,等到再走到标上1时,结束,统计数加1

void search(int M){
	int i=M;//一开始从这里开始
	while(!flag[b[i]]){//如果它的映射没被访问过,那么说明它还没有构成环
		i=b[i];//继续映射
		flag[i]=1;//标记已访问
	}
	return ;//返回
}
int C(){
	int tmp=0;
	for(int i=1;i<=N;i++) if(!flag[i]) flag[i]=1,search(i),tmp++;//环数加1
	return tmp;//返回循环节数
}

  那么我们再加上一个快速幂,就可以进一步优化。

时间: 2024-10-19 05:42:05

【群论】polya定理的相关文章

BZOJ 1488 [HNOI2009]图的同构 Polya定理

题意:链接 **方法:**Polya定理 解析: 先扯点题外话. 小雨淅沥的下午,PoPoQQQ爷在屠了一道题后放松心情,恰看见我把知识点上的群论标记已会. 于是,为了发扬D人的精神,PoPoQQQ爷打开了BZOJ,给我找了这么一个题,说:"这题都没做过还敢说会群论?" -- -- 征战半下午,卒. (我好菜以后再也不敢说我会啥了T_T (做这道题千万别去OEIS找通项=-=) 好不扯了,言归正传说这道题怎么做. 这道题确实是个好题,跟以前的群论的解法有共同点但是又有新的东西. 反正我

[BZOJ1004] [HNOI2008] Cards (Polya定理)

Description 小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿色.他询问Sun有多少种染色方案,Sun很快就给出了答案.进一步,小春要求染出Sr张红色,Sb张蓝色,Sg张绝色.他又询问有多少种方案,Sun想了一下,又给出了正确答案. 最后小春发明了M种不同的洗牌法,这里他又问Sun有多少种不同的染色方案.两种染色方法相同当且仅当其中一种可以通过任意的洗牌法(即可以使用多种洗牌法,而每种方法可以使用多次)洗成另一种.Sun发现这个问题有点难度,决

UVa 10294 Arif in Dhaka (First Love Part 2) Polya定理

题目来源:UVa 10294 Arif in Dhaka (First Love Part 2) 题意:n颗珠子t种颜色 求有多少种项链和手镯 项链不可以翻转 手镯可以翻转 思路:Polya定理  题目就是求等价类 项链只能旋转 手镯可以旋转也可以翻转 根据定理 等价类的数量等于各个置换f的t^m(f)的平均数 m(f)是置换的循环节数 下面每次t^x x都是循环节数 下面考虑手镯 旋转翻转都算 对于旋转 可以旋转0,1,...,n-1 每一个置换的循环节为gcd(0,n), gcd(1,n),

HDU 3923 Invoker 【裸Polya 定理】

参考了http://blog.csdn.net/ACM_cxlove?viewmode=contents           by---cxlove 的模板 对于每一种染色,都有一个等价群,例如旋转,翻转等.我们将每一种变换转换成一个置换群,通过置换群得到的都是等价的染色方案 最终我们要求的是非等价的染色方案数. 在Burnside定理中给出,在每一种置换群也就是等价群中的数量和除以置换群的数量,即非等价的着色数等于在置换群中的置换作用下保持不变的着色平均数. 我们以POJ 2409 Let i

poj 1286 Necklace of Beads &amp;amp; poj 2409 Let it Bead(初涉polya定理)

http://poj.org/problem?id=1286 题意:有红.绿.蓝三种颜色的n个珠子.要把它们构成一个项链,问有多少种不同的方法.旋转和翻转后同样的属于同一种方法. polya计数. 搜了一篇论文Pólya原理及其应用看了看polya究竟是什么东东.它主要计算所有互异的组合的个数.对置换群还是似懂略懂.用polya定理解决这个问题的关键是找出置换群的个数及哪些置换群,每种置换的循环节数.像这样的不同颜色的珠子构成项链的问题能够把N个珠子看成正N边形. Polya定理:(1)设G是p

【Polya定理】poj1286 Necklace of Beads

Polya定理:设G={π1,π2,π3........πn}是X={a1,a2,a3.......an}上一个置换群,用m中颜色对X中的元素进行涂色,那么不同的涂色方案数为:1/|G|*(mC(π1)+mC(π2)+mC(π3)+...+mC(πk)). 其中C(πk)为置换πk的循环节的个数. Polya定理的基础应用. 你得算出旋转和翻转时,每种置换的循环节数. 旋转时,每种置换的循环节数为gcd(n,i): 翻转时,若n为奇数,共有n个循环节数为n+1>>1的置换, 若n为偶数,共有n

hdu 3547 (polya定理 + 小高精)

DIY CubeTime Limit: 2000/2000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 207    Accepted Submission(s): 111 Problem Description Mr. D is interesting in combinatorial enumeration. Now he want to find out the numb

polya定理小结

polya的精髓就在与对循环节的寻找,其中常遇到的问题就是项链染色类问题. 当项链旋转时有n种置换,循环节的个数分别是gcd(n, i); 当项链翻转时有n种置换,其中当项链珠子数位奇数时,循环节的个数是n/2+1 当项链珠子数是偶数个时,当翻转线穿过珠子时,循环节个数为n/2+1,否则为n/2; 1.poj 1286: 题目大意:用三种颜色对珠子数不超过24的项链染色,问有多少种染色情况. 这道题是最基本的polya定理考察,只要带入公式即可 #include<iostream> #incl

poj 2409 polya定理

polya定理的入门题 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 int pow( int a, int n ) 7 { 8 int r = 1; 9 while ( n-- ) 10 { 11 r = r * a; 12 } 13 return r; 14 } 15 16 int gcd( int a, int b ) 17 { 1