您的位置:首页 > 其它

POJ 2409 Let it Bead(Polya定理)

2017-10-02 13:22 483 查看
Let it Bead

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 6122 Accepted: 4106
Description

"Let it Bead" company is located upstairs at 700 Cannery Row in Monterey, CA. As you can deduce from the company name, their business is beads. Their PR department found out that customers are interested in buying colored bracelets. However, over 90 percent
of the target audience insists that the bracelets be unique. (Just imagine what happened if two women showed up at the same party wearing identical bracelets!) It's a good thing that bracelets can have different lengths and need not be made of beads of one
color. Help the boss estimating maximum profit by calculating how many different bracelets can be produced. 

A bracelet is a ring-like sequence of s beads each of which can have one of c distinct colors. The ring is closed, i.e. has no beginning or end, and has no direction. Assume an unlimited supply of beads of each color. For different values of s and c, calculate
the number of different bracelets that can be made.
Input

Every line of the input file defines a test case and contains two integers: the number of available colors c followed by the length of the bracelets s. Input is terminated by c=s=0. Otherwise, both are positive, and, due to technical difficulties in the bracelet-fabrication-machine,
cs<=32, i.e. their product does not exceed 32.
Output


For each test case output on a single line the number of unique bracelets. The figure below shows the 8 different bracelets that can be made with 2 colors and 5 beads.
Sample Input
1 1
2 1
2 2
5 1
2 5
2 6
6 2
0 0

Sample Output
1
2
3
5
8
13
21

Source

Ulm Local 2000
[Submit]   [Go Back]   [Status]  
[Discuss]


Home Page   

Go
Back  

To top

题意:给你m种颜色和n个珠子组成的项链,让你用这m种颜色染项链,问你有多少种染色方案。
两个项链一样当且仅当该项链通过旋转和翻转能重叠。
题解:polya定理的应用。
一篇讲解文库:https://wenku.baidu.com/view/bf92a95f804d2b160b4ec0be.html
相对于Burnside引理,该定理时间复杂度较低,也较简便。什么是polya定理?





置换就简单的说一下吧,就拿本题来说,因为我们有旋转和翻转,因为旋转有任意角度的旋转,本题是任意数量
珠子的旋转,反转同理,因此置换群的元素个数便是2*n。
呢么我们便来分析两种置换下的方案数。
(1)旋转:假设我们一次旋转i个珠子(假定为顺时针方向),呢循环节数是多少呢?很容易想到,一定是gcd(n,i)、
呢么每种旋转对答案的贡献便是pow(n,gcd(n.i));
(2)翻转:这时候要对n的奇偶性进行判断了。
当n为奇数时:我们选择一个点作为中心点或者对称点进行翻转。此时很容易发现,循环节个数为n/2+1
当n为偶数时:我们可以找相对的两点作为对称轴进行翻转,此时循环节个数为(n+2)/2。
还有一种翻转便是将相邻两点的中点作为对称轴进行翻转。此时循环节为n/2。
然后ans/(置换群总个数)即可。
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<vector>
#include<string>
#include<time.h>
#include<math.h>
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<functional>
using namespace std;
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define maxn 20005
#define lowbit(x) (x&-x)
#define eps 1e-9
int gcd(int x,int y)
{
if(y==0)
return x;
return gcd(y,x%y);
}
int q(int x,int y)
{
int res=1;
while(y)
{
if(y%2)
res=res*x;
x=x*x;
y/=2;
}
return res;
}
int main(void)
{
int n,m,i,j,sum;
while(scanf("%d%d",&m,&n)!=EOF)
{
if(n==0 && m==0)
break;
int ans=0;
for(i=1;i<=n;i++)
{
int tmp=gcd(n,i);
ans+=q(m,tmp);
}
if(n%2)
ans+=n*q(m,(n+1)/2);
else
{
ans+=n/2*q(m,(n+2)/2);
ans+=n/2*q(m,n/2);
}
ans=ans/2/n;
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: