POJ 1286 polya组合数定理
2016-04-29 18:51
253 查看
题目
Necklace of BeadsTime 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; }
相关文章推荐
- 初学ACM - 组合数学基础题目PKU 1833
- POJ ACM 1001
- POJ ACM 1002
- 1611:The Suspects
- POJ1089 区间合并
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers
- POJ 2773 HAPPY 2006
- POJ 3090 Visible Lattice Points
- POJ-2409-Let it Bead&&NYOJ-280-LK的项链
- POJ-1695-Magazine Delivery-dp
- POJ1523 SPF dfs
- POJ-1001 求高精度幂-大数乘法系列
- POJ-1003 Hangover
- POJ-1004 Financial Management
- POJ1050 最大子矩阵和
- 用单调栈解决最大连续矩形面积问题
- 2632 Crashing Robots的解决方法
- 1573 Robot Motion (简单题)
- POJ 1200 Crazy Search(简单哈希)