poyla计数问题
关于poyla定理,首先推荐两篇很好的文章阅读
2001-----符文杰《poyla原理及其应用》
2008-----陈瑜希《poyla计数法的应用》
在然后就是自己的学习笔记啦,据说《组合数学》一书当中讲得比较好,不过没看过,有机会找来看看
关于知识点嘛,下面给出一些:
(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阶循环。每个置换都可以写若干互不相交的循环的乘积,两个循环(a1a2…an)和(b1b2…bn)互不相交是指ai!=bj, i,j=1,2,…,n。例如:
设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)。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int gcd(int a,int b)
{
if(b==0) return a;
else
return gcd(b,a%b);
}
int main()
{
int c,n;
while(cin>>c>>n)
{
if(c==0&&n==0)
break;
int ans=0;
for(int i=1;i<=n;i++)
ans+=pow(c*1.0,gcd(n,i));
if(n&1)
ans+=n*pow(c*1.0,n/2+1);
else
ans+=n/2*(pow(c*1.0,n/2+1)+pow(c*1.0,n/2*1.0));
cout<<ans/(2*n)<<endl;
}
return 0;
}
poj1286
链接:http://poj.org/problem?id=1286
题解:跟上题相同,只是变成了3个,可以说是上题的简化版
注意long long
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int gcd(int a,int b)
{
if(b==0) return a;
else
return gcd(b,a%b);
}
int main()
{
int n;
while(cin>>n)
{
if(n==-1)
break;
long long sum=0;
for(int i=1;i<=n;i++)
sum+=pow(3*1.0,gcd(n,i));
if(n&1)
sum+=n*(pow(3*1.0,n/2+1));
else
sum+=n/2*(pow(3*1.0,n/2*1.0)+pow(3*1.0,n/2+1));
if(n<=0)
cout<<0<<endl;
else
cout<<sum/(2*n)<<endl;
}
return 0;
}
二.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)。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int n,m=0,test,mod;
bool col[50000];
int a[32000];
void prime(int n)
{
for(int i=2;i<=n;i++)
{
if(!col[i])
{
a[++m]=i;
for(int j=i*i;j<=n;j+=i) col[i]=true;
}
}
}
int quick(int a,int b)
{
int temp=1;
for(a%=mod;b;b>>=1)
{
if(b&1) temp=temp*a%mod;
a=a*a%mod;
}
return temp%mod;
}
int euler_phi(int n)
{
int temp=n;
for(int i=1;i*i<=m,a[i]*a[i]<=n;i++)
if(n%a[i]==0)
{
temp=temp/a[i]*(a[i]-1);
while(n%a[i]==0) n/=a[i];
}
if(n>1) temp=temp/n*(n-1);
return temp%mod;
}
int main()
{
int t;
cin>>t;
prime(32000);
while(t--)
{
int ans=0,i;
cin>>n>>mod;
for(i=1;i*i<n;i++)
if(n%i==0) ans=(ans+euler_phi(i)*quick(n,n/i-1)+euler_phi(n/i)*quick(n,i-1))%mod;
if(i*i==n) ans=(ans+euler_phi(i)*quick(n,i-1))%mod;
cout<<ans<<endl;
}
return 0;
}
poyla计数问题的更多相关文章
- 一些gcd计数问题
数论什么的全都忘光了吧QAQ 做了几道简单的题练习一下. bzoj1101: [POI2007]Zap 求有多少对数满足 gcd(x,y)=d, 1<=x<=a, 1<=y<= ...
- 扩展Python模块系列(四)----引用计数问题的处理
承接上文,发现在使用Python C/C++ API扩展Python模块时,总要在各种各样的地方考虑到引用计数问题,稍不留神可能会导致扩展的模块存在内存泄漏.引用计数问题是C语言扩展Python模块最 ...
- 置换群、Burnside引理与等价类计数问题
置换群.Burnside引理与等价类计数问题 标签: 置换群 Burnside引理 置换 说说我对置换的理解,其实就是把一个排列变成另外一个排列.简单来说就是一一映射.而置换群就是置换的集合. 比如\ ...
- [HEOI2013]SAO ——计数问题
题目大意: Welcome to SAO ( Strange and Abnormal Online).这是一个 VR MMORPG, 含有 n 个关卡.但是,挑战不同关卡的顺序是一个很大的问题. 有 ...
- cojs 二分图计数问题1-3 题解报告
OwO 良心的FFT练手题,包含了所有的多项式基本运算呢 其中一部分解法参考了myy的uoj的blog 二分图计数 1: 实际是求所有图的二分图染色方案和 我们不妨枚举这个图中有多少个黑点 在n个点中 ...
- LOJ #6089. 小 Y 的背包计数问题
LOJ #6089. 小 Y 的背包计数问题 神仙题啊orz. 首先把数分成\(<=\sqrt n\)的和\(>\sqrt n\)的两部分. \(>\sqrt n\)的部分因为最多选 ...
- 【LOJ6089】小Y的背包计数问题(动态规划)
[LOJ6089]小Y的背包计数问题(动态规划) 题面 LOJ 题解 神仙题啊. 我们分开考虑不同的物品,按照编号与\(\sqrt n\)的关系分类. 第一类:\(i\le \sqrt n\) 即需要 ...
- Project Euler 453 Lattice Quadrilaterals 困难的计数问题
这是一道很综合的计数问题,对于思维的全面性,解法的过渡性,代码能力,细节处理,计数问题中的各种算法,像gcd.容斥.类欧几里德算法都有考察.在省选模拟赛中做到了这题,然而数据范围是n,m小于等于100 ...
- Codeforces 1109D (树的计数问题)
思路看这篇博客就行了:https://www.cnblogs.com/zhouzhendong/p/CF1109D.html, 讲的很好 今天学到了prufer编码,这是解决树上计数问题的一大利器,博 ...
随机推荐
- VIM键盘图
- 复(学)习化学时突然的一个 idea
期中考试成功探底...但是某些化学问题还是很有信息学价值的... n 烷同分异构体计数. 这个题 fanhq666 出过,就是一个 dp. 设 f[i] 表示含有 i 个节点的无标号不同构的度数限制为 ...
- 海战(洛谷 P1331)
题目描述 在峰会期间,武装部队得处于高度戒备.警察将监视每一条大街,军队将保卫建筑物,领空将布满了F-2003飞机.此外,巡洋船只和舰队将被派去保护海岸线.不幸的是因为种种原因,国防海军部仅有很少的几 ...
- MySQL的字符串连接函数CONCAT, CONCAT_WS,GROUP_CONTACT
本文转载自de.cel<MySQL的字符串连接函数CONCAT, CONCAT_WS,GROUP_CONCAT> 在搜索Mysql中怎么实现把一列的多行数据合并成一行时,找到了grou ...
- SpringDataJPA入门2
SpringDataJPA实体概述 JPA提供了一种简单高效的方式来管理Java对象(POJO)到关系型数据库的映射,此类Java对象成为JPA实体或简称实体.实体通常与底层数据库中的单个关系表相关联 ...
- Eclipse中Maven运行项目时在Console中无日志出现的问题解决
这是由于工作空间损坏造成的,比如重装JDK后,或者重装Maven后这些问题.解决方法如下: 1.删除现有工作空间,重新选择一个新的. 2.重置Workspece. 3.可能是Maven版本太新导致的, ...
- Mac 使用smb协议连接FTPserver
在Mac中,能够通过smb协议作为client连接到server,比如一个FTPserver,然后获取上面的共享文件. 方法: 1.在Finder菜单中点击前往 -- 连接server. 也能够Com ...
- Windows 8.1更新变化
在上个月微软公布了Windows 8.1更新(KB2919355),假设大家使用的是Windows 8.1的系统,而且启用了自己主动更新,那这个更新就会被自己主动安装.伴随着这个更新,微软同一时 ...
- C# 谁改了我的代码 使用 Resharper 快速做适配器
C# 谁改了我的代码 本文告诉大家一个特殊的做法,可以修改一个字符串常量 我们来写一个简单的程序,把一个常量字符串输出 private const string str = "linde ...
- Android:内存控制及OOM处理
1. OOM(内存溢出)和Memory Leak(内存泄露)有什么关系? OOM可能是因为Memory Leak,也可能是你的应用本身就比较耗内存(比如图片浏览型的).所以,出现OOM不一定是Me ...