poj 1286 Necklace of Beads (polya(旋转+翻转)+模板)
Description
Beads of red, blue or green colors are connected together into a circular necklace of n beads ( n < ). 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.
- 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
-
Sample Output
Source
1、题目类型:Polya定理、组合数学、置换群。
2、解题思路:Polya定理:(1)设G是p个对象的一个置换群,用k种颜色突然这p个对象,若一种染色方案在群G的作用下变为另一种方案,则这两个方案当作是同一种方案,这样的不同染色方案数为:
;
(2)置换及循环节数的计算方法:对于有n个位置的手镯,有n种旋转置换和n种翻转置换.
对于旋转置换: c(fi) = gcd(n,i) i为一次转过i颗宝石( i = 0 时 c=n;);
对于翻转置换:如果n为偶数:c(f) = n/2 的置换有n/2个;
c(f) = n/2+1 的置换有n/2个;
如果n为奇数:c(f) = n/2+1.
3、注意事项:注意对于翻转置换过程中对于奇偶数情况的区分处理。
相同的gcd合并在一起计算:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<set>
#include<vector>
using namespace std;
#define ll long long
ll pow_mod(ll a,ll i){
if(i==)
return ;
ll t=pow_mod(a,i/);
ll ans=t*t;
if(i&)
ans=ans*a;
return ans;
} vector<ll> divisor(ll n){
vector<ll> res;
for(ll i=;i*i<=n;i++){
if(n%i==){
res.push_back(i);
if(i*i!=n){
res.push_back(n/i);
}
}
}
return res;
}
ll eular(ll n){
ll res=;
for(ll i=;i*i<=n;i++){
if(n%i==){
n/=i,res*=i-;
while(n%i==){
n/=i;
res*=i;
}
}
}
if(n>) res*=n-;
return res;
}
ll polya(ll m,ll n){
//map<ll,ll> primes = prime_factor(n);
vector<ll> divs = divisor(n);
ll res=;
for(ll i=;i<divs.size();i++){
ll euler=eular(divs[i]);
res+=euler*pow_mod(m,n/divs[i]);
}
res/=n;
return res;
}
int main()
{
ll n,m=;
while(~scanf("%I64d",&n) && n!=-){
if(n==){
puts("");
continue;
}
ll count=polya(m,n)*n;//旋转情况
if(n&){//奇数
count+=n*pow_mod(m,n/+);//翻转情况
}
else{//偶数
count += (pow_mod(m, n / + ) + pow_mod(m, n / )) * (n / );//翻转情况
}
count/=*n;
printf("%I64d\n",count);
}
return ;
}
附上大神代码:
相同的gcd合并在一起计算:
#include <iostream>
#include <map>
#include <vector>
using namespace std; #define LL long long inline LL power(LL p, LL n)
{
LL sum = ;
while (n)
{
if (n & )
sum *= p;
p *= p;
n /= ;
}
return sum;
} //************************************
// Method: divisor
// FullName: divisor
// Access: public
// Returns: vector<int> 约数
// Qualifier: 约数枚举
// Parameter: const int & n 目标数n
//************************************
vector<int> divisor(const int& n)
{
vector<int> res;
for (int i = ; i * i <= n; ++i)
{
if (n % i == )
{
res.push_back(i);
if (i != n / i)
{
res.push_back(n / i);
}
}
} return res;
} //************************************
// Method: prime_factor
// FullName: prime_factor
// Access: public
// Returns: map<int, int>
// Qualifier: 整数分解
// Parameter: int n
//************************************
map<int, int> prime_factor(int n)
{
map<int, int> res;
for (int i = ; i * i <= n; ++i)
{
while (n % i == )
{
++res[i];
n /= i;
}
}
if (n != )
{
res[n] = ;
}
return res;
} LL polya(const int& m, const int& n)
{
map<int, int> primes = prime_factor(n);
vector<int> divs = divisor(n);
LL res = ;
for (int i = ; i < divs.size(); ++i)
{
// 求divs[i]的欧拉函数值
LL euler = divs[i];
for (map<int, int>::iterator it = primes.begin(); it != primes.end(); ++it)
{
int p = it->first;
if (divs[i] % p == ) euler = euler / p * (p - );
} res += euler * power(m, n / divs[i]);
} // 最后除以n
res /= n;
return res;
} ///////////////////////////SubMain//////////////////////////////////
int main(int argc, char *argv[])
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int n; const LL m = ;
while (~scanf("%d", &n) && n != -)
{
if (n == )
{
puts("");
continue;
} LL count = polya(m, n) * n;
if (n & )
count += n * power(m, n / + );
else
count += (power(m, n / + ) + power(m, n / )) * (n / );
count /= * n;
printf("%lld\n", count);
}
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
system("out.txt");
#endif
return ;
}
还有一种暴力求法:
#include <iostream>
using namespace std; #define LL long long int gcd(int a, int b)
{
return b == ? a : gcd(b, a % b);
} LL power(LL p, LL n)
{
LL sum = ;
while (n)
{
if (n & )
sum *= p;
p *= p;
n /= ; }
return sum;
} ///////////////////////////SubMain//////////////////////////////////
int main(int argc, char *argv[])
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int n; const LL m = ;
while (~scanf("%d", &n) && n != -)
{
if (n == )
{
puts("");
continue;
}
LL count = ;
for (int i = ; i <= n; ++i)
count += power(m, gcd(i, n));
if (n & )
count += n * power(m, n / + );
else
count += n / * (power(m, n / + ) + power(m, n / ));
count /= n * ;
printf("%lld\n", count);
}
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
system("out.txt");
#endif
return ;
}
poj 1286 Necklace of Beads (polya(旋转+翻转)+模板)的更多相关文章
- poj 1286 Necklace of Beads & poj 2409 Let it Bead(初涉polya定理)
http://poj.org/problem?id=1286 题意:有红.绿.蓝三种颜色的n个珠子.要把它们构成一个项链,问有多少种不同的方法.旋转和翻转后同样的属于同一种方法. polya计数. 搜 ...
- POJ 1286 Necklace of Beads(Polya简单应用)
Necklace of Beads 大意:3种颜色的珠子,n个串在一起,旋转变换跟反转变换假设同样就算是同一种,问会有多少种不同的组合. 思路:正规学Polya的第一道题,在楠神的带领下,理解的还算挺 ...
- POJ 1286 Necklace of Beads(项链的珠子)
Necklace of Beads Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 7874 Accepted: 3290 ...
- poj 1286 Necklace of Beads poj 2409 Let it Bead HDU 3923 Invoker <组合数学>
链接:http://poj.org/problem?id=1286 http://poj.org/problem?id=2409 #include <cstdio> #include &l ...
- 数学计数原理(Pólya):POJ 1286 Necklace of Beads
Necklace of Beads Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 7763 Accepted: 3247 ...
- poj 2409 Let it Bead && poj 1286 Necklace of Beads(Polya定理)
题目:http://poj.org/problem?id=2409 题意:用k种不同的颜色给长度为n的项链染色 网上大神的题解: 1.旋转置换:一个有n个旋转置换,依次为旋转0,1,2,```n-1. ...
- POJ 1286 Necklace of Beads(Polya原理)
Description Beads of red, blue or green colors are connected together into a circular necklace of n ...
- POJ 1286 Necklace of Beads(Polya定理)
点我看题目 题意 :给你3个颜色的n个珠子,能组成多少不同形式的项链. 思路 :这个题分类就是polya定理,这个定理看起来真的是很麻烦啊T_T.......看了有个人写的不错: Polya定理: ( ...
- poj 1286 Necklace of Beads【polya定理+burnside引理】
和poj 2409差不多,就是k变成3了,详见 还有不一样的地方是记得特判n==0的情况不然会RE #include<iostream> #include<cstdio> us ...
随机推荐
- JavaScript 随机数函数
Math.random()*(m-n)+n random函数语法 Math.random(); random函数返回值 返回0和1之间的伪随机数,可能为0,但总是小于1,[0,1) 返回10-20 ...
- Gulp:静态资源(css,js)版本控制
为了防止客户端的静态资源缓存,我们需要每次更新css或js的时候,通过md5或时间戳等方式重新命名静态资源: 然后涉及到的html模板里的src也要做相应的修改,静态资源需要优化(压缩合并) 文件目录 ...
- Nyoj 43 24 Point game 【DFS】
24 Point game 时间限制:3000 ms | 内存限制:65535 KB 难度:5 描写叙述 There is a game which is called 24 Point game ...
- 10个热门IT证书
MCP (微软专家认证) CCNA (思科认证网络支持工程师) MCPD (微软认证开发专家) SCJP (SUN认证Java程序员) CISSP (信息系统安全认证专家) CompTIA A+认证 ...
- MODULE_DEVICE_TABLE
1. MODULE_DEVICE_TABLE (usb, skel_table);该宏生成一个名为__mod_pci_device_table的局部变量,该变量指向第二个参数.内核构建时,depmod ...
- Html.Action和Html.RederAction来创建子视图
1. 父视图和子视图 父视图是包含了调用返回子视图的动作方法的视图. 父视图包含大部分用于呈现页面的HTML.子视图仅包含用于展示视图某部分的必须的标记. 例如,一个子视图创建一个列表,视图可能仅仅包 ...
- (转)Jquery弹窗插件Lhgdialog的用法
Lhgdialog的用法 大家都知道用js可以实现,但是在使用js实现的弹窗时得考虑很东西:浏览器的兼容.页面的交互等等问题. 在这里简单介绍一下lhgdialog的用法. 参数有: Title:弹窗 ...
- ORACLE用户操作的一些常用操作总结【weber出品】
一.创建一个表空间 create tablespace pioneer_data datafile '/u01/datafile/pioneer_datadbf' size 100m autoexte ...
- UITableVIewcell中图片不能改变大小的原因
你有没没有发现,有时候把图片放进cell.imageView中时无法顺利改变大小呢? 其实根本原因是要在layoutSubviews重新配置一下,cell的布局里面默认有一个imageiView,同时 ...
- out返回值的用法与用途
static void Main(string[] arr) { Console.WriteLine("请输入用户名"); string uname = Console.ReadL ...