poj 1286 Necklace of Beads

 

Necklace of Beads

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 8976   Accepted: 3722

Description

Beads of red, blue or green colors are connected together into a circular necklace of n beads ( n < 24 ). If the repetitions that are produced by rotation around the center of the circular necklace or reflection to the axis of symmetry are all neglected, how many different forms of the necklace are there? 

Input

The input has several lines, and each line contains the input data n. 
-1 denotes the end of the input file. 

Output

The output should contain the output data: Number of different forms, in each line correspondent to the input data.

Sample Input

4
5
-1

Sample Output

21
39

题意

传送门

给出三种颜色,对一串n个小球的项链进行染色,两条项链不同必须满足旋转和翻转后不相同,求有多少不同的染色方案。

分析

polya定理的使用。

polya定理:

设G是n个对象的一个置换群, 用m种颜色染图这n个对象,则不同的染色方案数为:


$L = \frac{1}{|G|}(m^{c(p_1)}+m^{c(p_2)}+...+m^{c(p_k)})$


$c(p_i)$ 表示置换 $pi$ 的循环节数

对于旋转部分,每个置换的循环节可以求出,即旋转i个位置的置换的循环节数是gcd(i,n)

翻转部分,分两种情况考虑。

1、当n是奇数,那么选出一个球,固定,这个求两边的球两两交换。一共n个球,每个球都可以作为这个固定的球,所以一共有n个置换,每个的循环节都是(n-1)/2+1。

2、当n是偶数,在分成两种情况。

  • 选出对着的两个球,固定,这两球的两侧分别两两交换。一共有n/2个置换,每个置换的循环节都是(n-2)/2+2。
  • 选出相邻的两个球,以他们的中间为对称轴,两两交换。一共n/2个置换,每个置换的循环节都是n/2。

最后置换的个数就是2n

code

 1 #include<cstdio>
 2 
 3 typedef long long LL;
 4 
 5 LL gcd(int a,int b) {
 6     if (b==0) return a;
 7     return gcd(b,a%b);
 8 }
 9 LL ksm(int a,int b) {
10     LL ans = 1;
11     while (b) {
12         if (b & 1) ans = ans * a;
13         b >>= 1;
14         a = a * a;
15     }
16     return ans;
17 }
18 int main () {
19     LL n,ans;
20     while (~scanf("%lld",&n) && n!=-1) {
21         if (n==0) {
22             puts("0");continue;
23         }
24         ans = ksm(3,n);//不动
25         for (int i=1; i<n; ++i) { // 转n个相当于不动
26             ans += ksm(3,gcd(n,i));
27         }
28         if (n & 1) {
29             ans += n * ksm(3,(n-1)/2+1);
30         }
31         else {
32             ans += n/2*ksm(3,n/2);
33             ans += n/2*ksm(3,(n-2)/2+2);
34         }
35         printf("%lld\n",ans/(n*2));
36     }
37     return 0;
38 }

 

posted @ 2018-02-06 19:54  MJT12044  阅读(155)  评论(0编辑  收藏  举报