pku 1286 Necklace of Beads polya定理
http://poj.org/problem?id=1286
题意:
3种颜色对一个有n个顶点的圈着色,问有多少种不同的着色方法。对于通过旋转或者翻转得到的相同的着色视为一种;
思路:
Polya定理
设有n个对象,G是这n个对象上的置换群,用m种颜色涂染这n个对象,每个对象涂染一种颜色,问有多少种染色方案?一种染色方案在群G的作用下变为另一种方案,则这两种方案当作是一种方案。
方案数为
因为这里的有旋转与翻转两种所以|G|的个数为2*n |G|表示置换群的个数
View Code
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <set> #include <map> #include <string> #define CL(a,num) memset((a),(num),sizeof(a)) #define iabs(x) ((x) > 0 ? (x) : -(x)) #define maxn 50004 #define ll __int64 #define inf 0x7f7f7f7f #define MOD 100000007 #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 using namespace std; ll gcd(ll a,ll b) { if (b == 0) return a; else return gcd(b,a%b); } ll Pow(ll a,ll b) { ll s = 1; for (int i = 1; i <= b; ++i) s *= a; return s; } ll polya(ll c,ll n) { if (n == 0) return 0; ll sum = 0; for (int i = 1; i <= n; ++i) sum += Pow(c,gcd(i,n)); if (n&1) sum += n*Pow(c,n/2 + 1); else { sum += (n/2)*Pow(c,n/2) + (n/2)*Pow(c,n/2 + 1); } return sum/2/n; } int main() { ll n; while (~scanf("%I64d",&n)) { if (n == -1) break; printf("%I64d\n",polya(3,n)); } return 0; }
http://poj.org/problem?id=2409 一样的一题目。