关于poyla定理,首先推荐两篇很好的文章阅读

2001-----符文杰《poyla原理及其应用》

2008-----陈瑜希《poyla计数法的应用》

在然后就是自己的学习笔记啦,据说《组合数学》一书当中讲得比较好,不过没看过,有机会找来看看

关于知识点嘛,下面给出一些:

Pólya原理是组合数学中,用来计算全部互异的组合状态的个数的一个十分高效、简便的工具。
在介绍polya定理之前,先介绍几个概念
      群:给定一个集合G={a,b,c,…}和集合G上的二元运算,并满足:

(a) 封闭性:"a,bÎG, $cÎG,a*b=c。

(b) 结合律:"a,b,cÎG, (a*b)*c=a*(b*c)。

(c) 单位元:$eÎG,"aÎG, a*e=e*a=a。

(d) 逆元:"aÎG,$bÎG, a*b=b*a=e,记b=a-1。

则称集合G在运算*之下是一个群,简称G是群。一般a*b简写为ab。          
       置换:n个元素1,2,…,n之间的一个置换 表示1被1到n中的某个数a1取代,2被1到n中的某个数a2取代,直到n被1到n中的某个数an取代,且a1,a2,…,an互不相同。
       置换群:置换群的元素是置换,运算是置换的连接。 
       循环:记 

称为n阶循环。每个置换都可以写若干互不相交的循环的乘积,两个循环(a1a2…an)和(b1b2…bn)互不相交是指ai!=bj, i,j=1,2,…,n。例如:

这样的表示是唯一的。置换的循环节数是上述表示中循环的个数。例如(13)(25)(4)的循环节数为3。

其实,polya定理是burnside引理的一种特殊情况。。。至于burnside引理,这就不详细探讨了。。。
下面直接给出polya定理的公式:

   设G是p个对象的一个置换群,用m种颜色涂染p个对象,则不同染色方案为:

L=1/|G|(m^c(g1)+m^c(g2)+...+m^c(gs))

其中G={g1,…gs}   c(gi )为置换gi的循环节数(i=1…s)

好了,下面上一些题目

由于poyla定理实在是不好理解,所以先上一个裸题,本人天资愚钝,裸题也是看了两天才会做的,poyla定理更是理解了好几天,希望做后面的题能顺点,废话不说看题

1.poyla定理直接套公式类型

poj2409

链接:http://poj.org/problem?id=2409

题解:这是本人在实习阶段写的一道题

这两道题都是很裸的polya定理题,而且代码几乎一样,所以把他们放到一起。。。

至于polya定理的理论部分,可以看我的上一篇blog。。。

这两道题:

对于旋转的情况:共有n个置换,其中旋转k个位置的置换的循环节数为gcd(n,k)。——(|)证明如下

         对于翻转的情况:若n为奇数,则对称轴过一顶点和一边中点,n种置换,循环节长度n/2+1;若n为偶数,对称轴有两种,过两点和过两边中点,两者各有n/2种置换,前者          循环节长度为n/2+1,后者为n/2。

总共有2*n个置换。

这部分也很好理解。。。接下来我要来证明一下(|)。。。

假设旋转k个位置,因为polya定理要求在置换后元素不变的情况下每种置换的循环节数,所以当他旋转到他原来的位置时,

所经过的点数既是n的倍数,又是k的倍数,且是n和k的最小公倍数,即lcm(n,k);

因为每次旋k个位置,所以当前置换中循环的个数为lcm(n,k)/k;

所以每个置换的循环节数=n/(lcm(n,k)/k)=gcd(n,k)。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<cmath>
  5. using namespace std;
  6. int gcd(int a,int b)
  7. {
  8. if(b==0) return a;
  9. else
  10. return gcd(b,a%b);
  11. }
  12. int main()
  13. {
  14. int c,n;
  15. while(cin>>c>>n)
  16. {
  17. if(c==0&&n==0)
  18. break;
  19. int ans=0;
  20. for(int i=1;i<=n;i++)
  21. ans+=pow(c*1.0,gcd(n,i));
  22. if(n&1)
  23. ans+=n*pow(c*1.0,n/2+1);
  24. else
  25. ans+=n/2*(pow(c*1.0,n/2+1)+pow(c*1.0,n/2*1.0));
  26. cout<<ans/(2*n)<<endl;
  27. }
  28. return 0;
  29. }

poj1286

链接:http://poj.org/problem?id=1286

题解:跟上题相同,只是变成了3个,可以说是上题的简化版

注意long long

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<cmath>
  5. using namespace std;
  6. int gcd(int a,int b)
  7. {
  8. if(b==0) return a;
  9. else
  10. return gcd(b,a%b);
  11. }
  12. int main()
  13. {
  14. int n;
  15. while(cin>>n)
  16. {
  17. if(n==-1)
  18. break;
  19. long long sum=0;
  20. for(int i=1;i<=n;i++)
  21. sum+=pow(3*1.0,gcd(n,i));
  22. if(n&1)
  23. sum+=n*(pow(3*1.0,n/2+1));
  24. else
  25. sum+=n/2*(pow(3*1.0,n/2*1.0)+pow(3*1.0,n/2+1));
  26. if(n<=0)
  27. cout<<0<<endl;
  28. else
  29. cout<<sum/(2*n)<<endl;
  30. }
  31. return 0;
  32. }

二.poyla定理跟欧拉函数的综合运用

POJ2154

链接:http://poj.org/problem?id=2154

本题涉及知识点比较多:有素数筛法,快速幂,欧拉函数,poyla定理,是一道非常经典的综合题

Poj2154的N比较大,10^9的范围,但是只有旋转这种置换,没有翻转。

        如果我们按照O(n)的做法,即∑m^gcd(n,i),显然是要超时的,所以需要换一种思路来计算。 

        设循环节长度为a=gcd(n,i),则一个循环的长度为L=n/a。由以上两式可以得到gcd(L*a,k*a)=a,其中k为不超过L的整数。进一步化简得到gcd(L,k)=1,那么满足这个式子的         循环的个数,也就是k的个数,就是euler(L),euler代表欧拉函数(小于L且与L互质的数的个数)。

        所以答案就是(∑euler(L)*m^(n/L)) / n,本题中m=n,上式也就是(∑euler(L)*n^(n/L-1)。因此只需要枚举n的约数L,L从1枚举到sqrt(n)即可,因为另一个约数就是n/L。注意         当L*L=n的时候别重复算。时间复杂度O(n^0.5logn)。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<cmath>
  5. using namespace std;
  6. int n,m=0,test,mod;
  7. bool col[50000];
  8. int a[32000];
  9. void prime(int n)
  10. {
  11. for(int i=2;i<=n;i++)
  12. {
  13. if(!col[i])
  14. {
  15. a[++m]=i;
  16. for(int j=i*i;j<=n;j+=i) col[i]=true;
  17. }
  18. }
  19. }
  20. int quick(int a,int b)
  21. {
  22. int temp=1;
  23. for(a%=mod;b;b>>=1)
  24. {
  25. if(b&1) temp=temp*a%mod;
  26. a=a*a%mod;
  27. }
  28. return temp%mod;
  29. }
  30. int euler_phi(int n)
  31. {
  32. int temp=n;
  33. for(int i=1;i*i<=m,a[i]*a[i]<=n;i++)
  34. if(n%a[i]==0)
  35. {
  36. temp=temp/a[i]*(a[i]-1);
  37. while(n%a[i]==0) n/=a[i];
  38. }
  39. if(n>1) temp=temp/n*(n-1);
  40. return temp%mod;
  41. }
  42. int main()
  43. {
  44. int t;
  45. cin>>t;
  46. prime(32000);
  47. while(t--)
  48. {
  49. int ans=0,i;
  50. cin>>n>>mod;
  51. for(i=1;i*i<n;i++)
  52. if(n%i==0) ans=(ans+euler_phi(i)*quick(n,n/i-1)+euler_phi(n/i)*quick(n,i-1))%mod;
  53. if(i*i==n) ans=(ans+euler_phi(i)*quick(n,i-1))%mod;
  54. cout<<ans<<endl;
  55. }
  56. return 0;
  57. }

poyla计数问题的更多相关文章

  1. 一些gcd计数问题

    数论什么的全都忘光了吧QAQ 做了几道简单的题练习一下. bzoj1101: [POI2007]Zap 求有多少对数满足 gcd(x,y)=d, 1<=x<=a, 1<=y<= ...

  2. 扩展Python模块系列(四)----引用计数问题的处理

    承接上文,发现在使用Python C/C++ API扩展Python模块时,总要在各种各样的地方考虑到引用计数问题,稍不留神可能会导致扩展的模块存在内存泄漏.引用计数问题是C语言扩展Python模块最 ...

  3. 置换群、Burnside引理与等价类计数问题

    置换群.Burnside引理与等价类计数问题 标签: 置换群 Burnside引理 置换 说说我对置换的理解,其实就是把一个排列变成另外一个排列.简单来说就是一一映射.而置换群就是置换的集合. 比如\ ...

  4. [HEOI2013]SAO ——计数问题

    题目大意: Welcome to SAO ( Strange and Abnormal Online).这是一个 VR MMORPG, 含有 n 个关卡.但是,挑战不同关卡的顺序是一个很大的问题. 有 ...

  5. cojs 二分图计数问题1-3 题解报告

    OwO 良心的FFT练手题,包含了所有的多项式基本运算呢 其中一部分解法参考了myy的uoj的blog 二分图计数 1: 实际是求所有图的二分图染色方案和 我们不妨枚举这个图中有多少个黑点 在n个点中 ...

  6. LOJ #6089. 小 Y 的背包计数问题

    LOJ #6089. 小 Y 的背包计数问题 神仙题啊orz. 首先把数分成\(<=\sqrt n\)的和\(>\sqrt n\)的两部分. \(>\sqrt n\)的部分因为最多选 ...

  7. 【LOJ6089】小Y的背包计数问题(动态规划)

    [LOJ6089]小Y的背包计数问题(动态规划) 题面 LOJ 题解 神仙题啊. 我们分开考虑不同的物品,按照编号与\(\sqrt n\)的关系分类. 第一类:\(i\le \sqrt n\) 即需要 ...

  8. Project Euler 453 Lattice Quadrilaterals 困难的计数问题

    这是一道很综合的计数问题,对于思维的全面性,解法的过渡性,代码能力,细节处理,计数问题中的各种算法,像gcd.容斥.类欧几里德算法都有考察.在省选模拟赛中做到了这题,然而数据范围是n,m小于等于100 ...

  9. Codeforces 1109D (树的计数问题)

    思路看这篇博客就行了:https://www.cnblogs.com/zhouzhendong/p/CF1109D.html, 讲的很好 今天学到了prufer编码,这是解决树上计数问题的一大利器,博 ...

随机推荐

  1. zoj 2947 Abbreviation

    Abbreviation Time Limit: 2 Seconds      Memory Limit: 65536 KB When a Little White meets another Lit ...

  2. POJ-Crazy tea party,很好的一道数学题~~~

    Crazy tea party Time Limit: 1000MS   Memory Limit: 10000K        Description n participants of <& ...

  3. 【网络流】【待补】C. Heidi and Library (hard)

    http://codeforces.com/contest/802/problem/C

  4. 关于datetime,date,timestamp,year,time时间类型小结

    关于datetime,date,timestamp,year,time时间类型 datetime占用8个字节 日期范围:”1000-01-01 00:00:00” 到”9999-12-31 23:59 ...

  5. 【ZJOI2017 Round1练习&BZOJ4765】D1T3 普通计算姬(主席树,分块)

    题意: 思路:分块 使用树状数组维护sum[i]的前缀和 使用主席树维护root到u的路径上点的编号出现的个数 每次操作如果是修改就加入队列 如果是询问,考虑块内操作对询问的影响,每次在x点加上y会使 ...

  6. CritterAI与Recast Navigation寻路

    版权声明:本文为博主吴欣伟原创文章,未经博主允许不得转载. 前言 这篇文章写于去年,由于工作需要,故写出这个研究文档,发现网上有关此寻路库的中文资源十分稀少,故发布出来与诸位共享交流,如文中有不对之处 ...

  7. Python高级进阶(一)Python框架之Django入门

    传说中的Django Django由来 Django是一个开放源代码的Web应用框架,由Python写成.采用了MVC的框架模式,即模型M,视图V和控制器C.它最初是被开发来用于管理劳伦斯出版集团旗下 ...

  8. C# 通过T4自动生成代码

    通过T4模板生成代码,运行时实现 关键代码段:Host using Microsoft.VisualStudio.TextTemplating; using System; using System. ...

  9. P1918 保龄球 洛谷

    https://www.luogu.org/problem/show?pid=1918 题目描述 DL 算缘分算得很烦闷,所以常常到体育馆去打保龄球解闷.因为他保龄球已经打了几十年了,所以技术上不成问 ...

  10. Windows下SVN服务器及客户端的使用

    原文地址:windows下配置VisualSVN Server服务器 作者:Deem_passion 下载安装文件: 服务端安装文件:VisualSVN-Server-1.6.2 客户端安装文件:To ...