POJ 2409 Let it Bead (polya计数,burnside染色)

Description

"Let it Bead" company is located upstairs at 700 Cannery Row in Monterey, CA. As you can deduce from the company name, their business is beads. Their PR department found out that customers are interested in buying colored bracelets. However, over 90 percent of the target audience insists that the bracelets be unique. (Just imagine what happened if two women showed up at the same party wearing identical bracelets!) It's a good thing that bracelets can have different lengths and need not be made of beads of one color. Help the boss estimating maximum profit by calculating how many different bracelets can be produced. 

A bracelet is a ring-like sequence of s beads each of which can have one of c distinct colors. The ring is closed, i.e. has no beginning or end, and has no direction. Assume an unlimited supply of beads of each color. For different values of s and c, calculate the number of different bracelets that can be made.

Input

Every line of the input file defines a test case and contains two integers: the number of available colors c followed by the length of the bracelets s. Input is terminated by c=s=0. Otherwise, both are positive, and, due to technical difficulties in the bracelet-fabrication-machine, cs<=32, i.e. their product does not exceed 32.

Output

POJ 2409 Let it Bead (polya计数,burnside染色)_第1张图片For each test case output on a single line the number of unique bracelets. The figure below shows the 8 different bracelets that can be made with 2 colors and 5 beads.

Sample Input

1 1
2 1
2 2
5 1
2 5
2 6
6 2
0 0

Sample Output

1
2
3
5
8
13
21
 
 
本题是给定颜色种数c和环上的珠子数n,问有多少种染色方案(通过旋转和翻转相同算同一种)最后的结果不会超过int类型。

1.旋转。

将环顺时针旋转i格后,循环节个数为gcd(n,i), 染色方案为  ∑c^gcd(n,i)    其中 i=1,2,3,4,....n 这里的gcd是求的最大公约数

2.翻转。

这里也得考虑两种情况。

当n为奇数时,共有n个循环节个数为(n/2+1)的循环群,其实应该写成(n+1)/2。,染色方案为  n*c^(n/2+1)

为什么有n个循环群,并且每个循环群的循环节个数为(n/2+1)呢? 拿正三角形为例,给它三个顶点染色, 对称轴是一个顶点与其对边中点连线所在的直线,这样的直线有3(n=3,即n个顶点) 条,共有3个循环群。假设第一个顶点在对称轴上,那么第二个顶点经过对称轴翻转肯定和第三个顶点重合,那么 (2,3)是一个循环节,(1)自己是一个循环节,循环节个数为2,即(n/2+1)。

当n为偶数时,共有n个循环群,其中有n/2个循环群的循环节个数为(n/2 +1), 有n/2个循环群的循环节个数为(n/2)。

拿正方形为例,四个顶点从左上角顺时针编号1,2,3,4.  

当以1,3顶点连线所在直线为对称轴时(对角的两个顶点),这样对称轴有2个(n/2),经过翻转,2,4 重合,1和1重合,3和3重合,那么循环节的个数为3个,即(2,4)(1)(3), 即(n/2+1)。 染色方案为  (n/2)*c^(n/2+1)

当以两条相对平行的边的中点连线所在直线为对称轴时,比如以线段1,2的中点和3,4的中点连线的所在直线为对称轴,这样的对称轴有两个(n/2), 经过翻转,1,2重合,3,4重合,循环节的个数为2,(1,2)(3,4),即(n/2)。也就是谁和谁重合,谁就和谁在一个循环节里染色方案为(n/2)*c^(n/2)

POJ 2409 Let it Bead (polya计数,burnside染色)_第2张图片

#include <iostream>
using namespace std;
int gcd(int a,int b)
{
    return b==0?a:gcd(b,a%b);
}
int power(int p,int n)
{
    int ret=1;
    while(n)
    {
        if(n&1)ret=ret*p;
        p=p*p;
        n=n/2;
    }
    return ret;
}
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=ans+power(c,gcd(n,i));
        if(n&1)//是奇数,有n个包含(n/2+1)个循环节的循环群
            ans=ans+n*power(c,n/2+1);
        else
            ans=ans+(n/2)*(power(c,n/2+1)+power(c,n/2));
         ans=ans/(2*n);//别忘了除以置换群的总个数,这里由于既翻转又旋转所以是2*n
         cout<<ans<<endl;
    }
    return 0;
}
 

你可能感兴趣的:(POJ 2409 Let it Bead (polya计数,burnside染色))