关于数论【polya计数法】

可以预见数论推公式是有多么蛋疼。

让我简明扼要的讲讲吧(多都说不出来,毕竟才做了两道题)其实呢,这个算法应该归入群论,有个有用的东西:置换群,它表示一个集合包括很多的置换。
先讲讲置换吧:↓(这是个置换)
1 2 3 4
3 1 2 4
怎么个置换法呢?这个就代表,第1个状态置换后变成第3个状态,第2个状态置换后变成第1个状态,第3个状态置换后变成第2个状态,第4个状态置换后变成第4个状态。
然后就是循环节:
1 2 3 4 5
3 5 1 4 2
它等于:(13)(25)(4)
那循环节长度就等于3

嘿嘿,简单吧。

然后就是一个神奇的定理——polya定理,设这个群{g1,g2,……gG}G为置换群的置换数,c(g)表示这个置换的循环节长度,用m种颜色涂点,那不同的涂色方案为:m^c(g1)+m^c(g2)+m^c(gG)的和除以G(这个我实在是证不出来,死记吧),然而c(g)怎么理解?其实这个来源于Burnside引理,我们将其优化变成polya定理,那这个是什么?

burnside引理:用D(i)表示在置换中不变的个数,怎么理解?例如第一个置换,4就是不变的,那这个置换的D就等于1。那不同的涂色方案就等于ΣGi=1 *D(i)。这个循环节的想法,就是来自于这里的D,同时,由于polya有很大局限性(因为直接用polya题目就太简单啦T>*<T)所以说有很多题都是要用引理+优化。

例题:poj2409

#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
LL gcd(LL a,LL b)
{
    if(a==0)return b;
    return gcd(b%a,a);
}
LL power(LL A,LL k)
{
    LL ans=1;
    while(k!=0)
    {
        if(k%2==1)ans*=A;
        A*=A;k/=2;
    }
    return ans;
}
int main()
{
    LL n,m;
    while(scanf("%lld%lld",&m,&n)!=EOF)
    {
        if(n==0&&m==0)break;
        LL ans=0;

        for(int i=1;i<=n;i++)ans+=power(m,gcd(i,n));
        //旋转置换,枚举旋转的豆子个数,置换数为n,循环节长度为LCM(i,n)/i,循环节数为n/(LCM(i,n)/i)=gcd(i,n)
        //翻转置换
        if(n%2==1)//假如是奇数,就只有一种情况,n个豆子有n种置换,循环节为(n+1)/2
        {
            ans+=n*power(m,(n+1)/2);
        }
        else//假如是偶数,两种情况,对称轴过豆子或过间隔
        {
            ans+=n/2*power(m,n/2);//对称轴过间隔,所有豆子翻转,有n/2种置换,循环节为n/2
            ans+=n/2*power(m,(n+2)/2);//对称轴过豆子,两个豆子不变,其他翻转,有n/2种置换,循环节为(n+2)/2
        }
        printf("%lld\n",ans/(n*2));//G=n*2
    }
    return 0;
}
时间: 2024-08-29 09:16:09

关于数论【polya计数法】的相关文章

poj1286 polya计数法

这个题的意思是是给你一串珠子, 珠子可以绕中心旋转, 也可以轴对称, 问用三种颜色染这一串珠子有几种情况? 首先我们可以知道这个置换群中有2n个元素, 当n为奇数的时候为n*3^(n/2+1),  当n为偶数的时候分两种情况n/2*(3^(n/2)+3^(n^2+1)), 当旋转的时候有 sigma(3^d*phi(n/d))  d|n, 代码如下: #include <iostream> #include <algorithm> #include <vector> u

HDU 4633(polya计数

题目:用k种颜色给一个魔方染色,可以染每个面的9个小矩形,12条棱,8个顶点(总之就是有74个能染的地方),空间旋转后一样的视为相同,问有多少种不同的染色方案. 思路:裸的polya计数,但是这个立方体的对称群本来就很容易弄错...<组合数学>里有个例题提到立方体的对称群有24个元素,分别是: (1)恒等变换. (2)以两个相对面的中心相连作为对称轴,旋转(i)90,(ii)180,(iii)270度,每种有3个.共9种. (3)以两个相对棱的中点连线为对称轴翻转180度,有6种. (4)固定

BZOJ 1004: [HNOI2008]Cards Polya计数+DP

Polya计数+dp求满足对应循环的不动点有几个 1004: [HNOI2008]Cards Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 2046  Solved: 1212 [Submit][Status][Discuss] Description 小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿色.他询问Sun有多少种染色方案,Sun很快就给出了答案.进一步,小春要求染出Sr张红色,Sb张蓝色,S

1024. 科学计数法 (20)

科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式[+-][1-9]"."[0-9]+E[+-][0-9]+,即数字的整数部分只有1位,小数部分至少有1位,该数字及其指数部分的正负号即使对正数也必定明确给出. 现以科学计数法的格式给出实数A,请编写程序按普通数字表示法输出A,并保证所有有效位都被保留. 输入格式: 每个输入包含1个测试用例,即一个以科学计数法表示的实数A.该数字的存储长度不超过9999字节,且其指数的绝对值不超过9999. 输出格式: 对每个测

将258.369 double值转为内存表示(科学计数法)

前言 庖丁解牛 - <<庄子>> 庖丁为文惠君解牛,手之所触, 肩之所倚, 足之所履, 膝之所踦, 砉然向然, 奏刀騞然, 莫不中音, 合于<桑林>之舞, 乃中<经首>之会. 文惠君曰:"嘻, 善哉! 技盍至此乎?" 庖丁释刀对曰:"臣之所好者, 道也, 进乎技矣.始臣之解牛之时, 所见无非牛者.三年之后, 未尝见全牛也.方今之时, 臣以神遇而不以目视, 官知止而神欲行.依乎天理, 批大郤, 导大窾, 因其固然, 技经肯綮之未尝

组合数学及其应用——polya计数

在处理类似下面的问题中,一般的计数方法会出现问题:假如你要用红.蓝两种颜色给一个正四面体的四个顶点着色,试问存在多少种不同的着色方案? 在高中我们常用的方法是模拟涂色过程,分情况讨论,然后基于分步乘法原理.但是在那里没有考虑几何体通过旋转等操作带来的对称性,在本文中,我们就来介绍一种专门处理这类问题的工具——Polya计数. 首先我们要做的是引入一些基本的概念. 置换: 关于置换更多的细节我们在<抽象代数基础教程>中继续讨论,这里我们只需简单的了解其概念即可. 关于置换还需要了解的就是它的合乘

Jam的计数法

Jam的计数法 (count.pas/c/cpp) [问题描述] Jam是个喜欢标新立异的科学怪人.他不使用阿拉伯数字计数,而是使用小写英文字母计数,他觉得这样做,会使世界更加丰富多彩.在他的计数法中,每个数字的位数都是相同的(使用相同个数的字母),英文字母按原先的顺序,排在前面的字母小于排在它后面的字母.我们把这样的“数字”称为Jam数字.在Jam数字中,每个字母互不相同,而且从左到右是严格递增的.每次,Jam还指定使用字母的范围,例如,从2到10,表示只能使用{b,c,d,e,f,g,h,i

PAT 1024. 科学计数法 (20)

1024. 科学计数法 (20) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 HOU, Qiming 科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式[+-][1-9]"."[0-9]+E[+-][0-9]+,即数字的整数部分只有1位,小数部分至少有1位,该数字及其指数部分的正负号即使对正数也必定明确给出. 现以科学计数法的格式给出实数A,请编写程序按普通数字表示法输出A,并保证所有有效位

PAT乙级 1024. 科学计数法 (20)

1024. 科学计数法 (20) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 HOU, Qiming 科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式[+-][1-9]"."[0-9]+E[+-][0-9]+,即数字的整数部分只有1位,小数部分至少有1位,该数字及其指数部分的正负号即使对正数也必定明确给出. 现以科学计数法的格式给出实数A,请编写程序按普通数字表示法输出A,并保证所有有效位