POJ - 2409 Let it Bead
3、考虑翻转的置换
旋转的有n种,相对这n种的翻转也有n种
对于奇数,翻转情况只有一个点,和它对面的中点作为对称轴,一共n种,循环节为n/2+1
对于偶数,有两种情况,一个是两个对称点构成对称轴,n/2种,循环节为n/2+1
一个是两个中点构成对称轴,也是n/2种,循环节为n/2
综上,所有的置换总数有2*n种
对于置换群某种置换的循环节就是考虑置换后于原先相同
比如这里的偶数两个对称点的情况,如果是6个点,那么有3条对称点的对称轴,
翻转后相同所以3和2颜色要相同,5和6颜色要相同,1和4颜色可以不同,所以是n/2+1种颜色
#include<iostream>
#include<algorithm>
//#include<unordered_map>
#include<fstream>
#include<iomanip>
#include<string>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<stack>
#include<sstream>
#include<cstdio>
#include<ctime>
#include<cstdlib>
using namespace std;
const int mod1 = 9999973;
const int mod2 = 1e9 + 7;
typedef long long ll;
#define R register
inline ll read() {
int f = 1; ll x = 0; char s = getchar();
while (!isdigit(s)) { if (s == '-') f = -1; s = getchar(); }
while (isdigit(s)) { x = x * 10 + s - '0'; s = getchar(); }
return x * f;
}
//Polya定理 置换群
ll gcd(ll a, ll b) {
return b ? gcd(b, a % b) : a;
}
inline ll col(ll a, ll b) {
ll res = 1;
while (b--) {
res *= a;
}
return res;
}
int n, len;
int main() {
while (~scanf("%d %d", &n, &len), n | len) {
if (len == 0 | n == 0) {
puts("0");
continue;
}
ll ans = 0;
int temp = len;
for (int i = 1; i <= len; ++i) {
ll temp = gcd(len, i);
ans += col(n, temp);
}
if (len & 1) {
ans += len * col(n, (len + 1) / 2);
}
else {
ans += len / 2 * col(n, (len + 2) / 2);
ans += len / 2 * col(n, len / 2);
}
ans /= (2 * len);
printf("%lld\n", ans);
}
return 0;
}

浙公网安备 33010602011771号