现在的位置: 首页 > 综合 > 正文

poj 2409 Let it Bead(polya定理)

2017年11月16日 ⁄ 综合 ⁄ 共 929字 ⁄ 字号 评论关闭


Polya定理
设G={a1,a2,...,a|G|}是N={1,2,...,N}上的置换群,现用m种颜色对这N个点染色,则不同的染色方案数为

    S=(m^c1+m^c2+...+m^c|G|)/|G|
证明比较复杂,略


常见置换的循环数
计算置换的循环数,是这一算法的瓶颈.如果能够快速计算出各置换的循环数,就可以大大提高程序的运行效率
旋转:

           s个点顺时针(或逆时针)旋转i个位置的置换,循环数为gcd(n,i)
翻转:
       s为偶数时,
       对称轴不过顶点:循环数为s/2
      对称轴过顶点:循环数为s/2+1
       n为奇数时,循环数为(s+1)/2

分析:1).有1,2....s个旋转;ans+=pow(c,gcd(s,i));i=1......s;(s,代表珠子个数)

           2).有s个翻转。

                     s为偶数时,有n/2个对称轴过顶点,有n/2个对称轴不过顶点;

                           ans+=(s/2)*pow(c*1.0,s/2.0)+(s/2)*pow(c*1.0,s/2.0+1);

                    s为奇数时,s*pow(c*1.0,(s+1)/2*1.0);

        3)ans=ans/(s+s);



#include<iostream>

#include<cstdio>

#include<math.h>
using namespace std;
int gcd(int x,int y)
{
return y==0?x:gcd(y,x%y);
}
int main()
{
int c,s;
while(cin>>c>>s)
{
  int l=0,g=s,i;
       if(c==0&&s==0)
  break;
  for(i=1;i<=s;i++)//Ðýת
  {
  l+=(int)pow(c*1.0,gcd(s,i)*1.0);
  }
  if(s%2==1)//·­×ª
  {
          l+=s*pow(c*1.0,(s+1)/2*1.0);
  }
  else
  {
 l+=(s/2)*pow(c*1.0,s/2.0)+(s/2)*pow(c*1.0,s/2.0+1);
  }
  l/=(g+s);
  cout<<l<<endl;
}
    return 0;
}

抱歉!评论已关闭.