polya定理应用

本文介绍了Polya定理在解决置换群问题中的应用,包括优化欧拉函数和快速幂运算。通过实例分析了如何利用Polya定理处理不同情况,如poj 2409和2154题,讨论了置换群的最小交换权问题(poj 3270),以及字符串处理中的周期计算(poj 1026)。此外,还涉及了判断字符串是否为某字串平方的问题(poj 3128)。
摘要由CSDN通过智能技术生成
 

TT_last 原创,转载请注明。

polya定理不知道可先看潘震皓的 《置换群快速幂运算研究与探讨》,下面是根据论文所做的一些题目。

poj 2409

 很裸的一道polya定理应用题目,

处理的状态有:一个点顺时针旋转 0 ~ n-1 个点

还有就是对称旋转的情况:

当n为偶数时:有两个对应的点相连线 和两条对应线段中点连线 分别形成的对称轴

当n为奇数时:仅有一个点与对应直线形成对称轴。

 

 #include <iostream>
#include <cmath>
using namespace std;
int c,s;
int gcd(int a,int b)
{
    if(b == 0) return a;
    else  return gcd(b,a%b);
}
int polya(int n,int m)
{
    int ans,i;
    __int64 tmp = 0;
    for(i = 0;i < n;i ++)
    {
       tmp += pow(m*1.0,1.0*gcd(n,i)); //n个循环  移动多少位。 
    }
    if(n&1)
    {
      tmp += n*pow(m*1.0,(n+1)/2.0);  //n个循环  一个点与对应线段中点连线 
    }else
    {
      tmp += n/2*pow(m*1.0,n/2+1)+n/2*pow(m*1.0,n/2);  //n个循环  分别为两个点连线 两条相对线段中点连线。
    }
    ans = tmp/(2*n);
    return ans;
}
int main()
{
    while(scanf("%d%d",&c,&s),c|s)
    {
       printf("%d\n",polya(s,c));
    }
    return 0;
}


 

poj 2154

 /*
 欧拉函数 + 快速幂 + 筛选质因数
*/

原本n很大,如果按照前面的做法去做 从1 ~ n,不断枚举,那肯定要tle,这里需要用欧拉函数优化一下。

根据polya定理:方案数(先不考虑取余):

for(i = 0;i < n;i ++)

   ans += pow(n,gcd(n,i));

从中,如果我们提取相同的gcd(n,i) 和取得它们的个数,那么时间复杂度将会减少很多。

设 m = gcd(n,i);m可以肯定是n的因子,而m = gcd(n,i),的个数就是 1 = gcd(n/m,i/m)的i/m个数,

这个可以用欧拉函数来求 euler(n/i);然后再根据polya定理做一下也就可以了。

 

#include <iostream>
using namespace std;
const int maxn = 32000;
int n,m,tmp;
int p[maxn],num,a[400],b[400],ans;
bool sign[maxn];
void init()
{
 int i,j;
 num = 0;
 p[num++] = 2;
 for(i = 4;i < maxn;i += 2) sign[i] = true;
 for(i = 3;i < maxn;i ++)
 {
  if(!sign[i])
  {
   p[num++] = i;
   for(j = i*i;j < maxn;j += i)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值