###POJ-2409 Let it Bead

m个珠子n种颜色,求一共能制造出多少串不同的珠子。

Pólya定理,先求置换群。

1.旋转置换

依次顺时针旋转1 ~ n个,循环个数为gcd(i, n)

2.翻转置换

当n为偶数时,分两种情况,一种是中心轴在两个对称对象上,则循环个数为n/2+1,另一种是对称轴两边分别有n/2个对象,则循环个数为n/2;

当n为奇数时,对称轴就只能在一个对象上,则循环个数为n/2+1;

POJ 2409
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//By Brickgao
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <vector>
using namespace std;
#define out(v) cerr << #v << ": " << (v) << endl
#define SZ(v) ((int)(v).size())
const int maxint = -1u>>1;
template <class T> bool get_max(T& a, const T &b) {return b > a? a = b, 1: 0;}
template <class T> bool get_min(T& a, const T &b) {return b < a? a = b, 1: 0;}

int c, s, ans;

int gcd(int a, int b) {
if(b == 0) return a;
return gcd(b, a % b);
}

void solve() {
int t = 0;
ans = 0;
for(int i = 1; i <= s; i ++) {
ans += pow(c, gcd(i, s));
t ++;
}
if(s % 2 == 0) {
for(int i = 0; i < s / 2; i ++) {
ans += pow(c, s / 2);
t ++;
}
for(int i = 0; i < s / 2; i ++) {
ans += pow(c, s / 2 + 1);
t ++;
}
}
else {
for(int i = 0; i < s; i ++) {
ans += pow(c, s / 2 + 1);
t ++;
}
}
ans /= t;
}

int main() {
while(scanf("%d%d", &c, &s) != EOF) {
if(c == 0 && s == 0) {
return 0;
}
solve();
printf("%d\n", ans);
}
return 0;
}

###POJ-1286 Necklace of Beads

比上一题说的还清楚,规定了颜色数,解法同上题。