题目
Necklace of Beads
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 7528 Accepted: 3134
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个,用这个n个珠子围成一个圆形的项链。两个项链认为是不同的单且仅当这两个项链不能通过旋转或者沿某一轴翻转成和原来的项链一样。
题解
此题是poj2409的弱化版
polya定理运用群论(置换群,对称群)给出一个公式来计算不同变换方式的组合数
《算法艺术和信息学竞赛》上写到
设G是p个对象的一个置换群,用k个颜色涂染这p个对象,若有一种染色方案在群G的作用下变为另一种方案,则这两个方案是同一种方案,这样不同的染色方案数为:
c(f)为置换群f的循环节
本题直接用模板就行了。关于polya更深的理解可以看《组合数学》这本书的记录
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
#include <string>
#include <set>
#include <cmath>
#include <map>
#include <queue>
#include <sstream>
#include <vector>
#include <iomanip>
#define m0(a) memset(a,0,sizeof(a))
#define mm(a) memset(a,0x3f,sizeof(a))
#define m_1(a) memset(a,-1,sizeof(a))
#define f(i,a,b) for(i = a;i<=b;i++)
#define fi(i,a,b) for(i = a;i>=b;i--)
#define lowbit(a) ((a)&(-a))
#define FFR freopen("data.in","r",stdin)
#define FFW freopen("data.out","w",stdout)
#define INF 0x3f3f3f3f
typedef long long ll;
typedef long double ld;
const ld PI = acos(-1.0);
using namespace std;
#define SIZE ( )
ll gcd(ll a, ll b) {
if (!b) {
return a;
} else {
gcd(b, a%b);
}
}
ll mod_pow(ll x, ll n) {
ll res = 1;
while (n>0) {
if (n & 1) res = res*x;
x = x*x;
n >>= 1;
}
return res;
}
int main() {
//ios_base::sync_with_stdio(false); cin.tie(0);
int n;
while (~scanf("%d",&n)&&n!=-1) {
if (!n) {
printf("0\n");
continue;
}
ll ans = 0;
int i;
f(i, 1, n)
ans += mod_pow(3, __gcd(n, i));
ans /= n;
ll tem = mod_pow(3, (n + 1) >> 1);
if (n & 1)
printf("%I64d\n", (ans + tem) >> 1);
else
printf("%I64d\n", ((tem * 4 / 2) + ans)>>1);
}
return 0;
}