先讲Burnside定理:
百度百科的传送门:https://baike.baidu.com/item/burnside%E5%BC%95%E7%90%86/1505996
再放一个例题:
重点还是Polya定理
百度百科的传送门:https://baike.baidu.com/item/Polya/11020869
Polya定理在Burnside定理的基础上增加了 翻转 得到更大的置换群
( )内表示的是 循环节
关于定理概念也可以看看这篇博客:https://blog.csdn.net/lyc1635566ty/article/details/52545355
Necklace of Beads
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 9432 | Accepted: 3887 |
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的项链有多少种。
(输入为 -1 时结束程序)
【因为 项链是一个圈 是可以翻转旋转的 所以用Polya定理做】
放代码
#include
#include
#include
#include
#include
#define LL long long
using namespace std;
//Polya定理 置换群
LL gcd(LL a,LL b)//计算最大公约数
{
if (b==0)
return a;
return gcd(b,a%b);
}
int main()
{
LL t;
while (~scanf("%lld",&t))
{
LL sum=0;
if (t==-1)break;
if (t==0)//特殊判断 输入0输出0
{
printf("0\n");
continue;
}
for (int i=1;i<=t;++i)
{
LL tmp=gcd(t,i);
sum+=(LL)(pow(3.0,tmp*1.0));//位置不变时 所有的点都有三种情况
}
if (t%2==1)//判断t的奇偶
sum+=(t*pow(3.0,(t+1)/2));//奇数情况下 置换造成的情况数量相同
else//偶数情况时
{
sum+=(LL)((t/2)*pow(3.0,(t+2)/2.0));//对角线对称翻转
sum+=(LL)((t/2)*pow(3.0,t/2));//对边对称翻转
}
sum=sum/(2*t);
printf("%lld\n",sum);
}
return 0;
}
Let it Bead
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 6487 | Accepted: 4339 |
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
题目大意:
每一行输入 e 和 s 求出 能由 e 种不同颜色的珠子串成的长度为 s 的手镯有多少种。
输入e=0且s=0时 结束程序
【注解中解释了gcd函数的作用】
放代码
#include
#include
#include
#include
#include
#define LL long long
using namespace std;
//Polya定理
LL gcd(LL a,LL b)//最大公约数 greatest common divisor
{
if (b==0)return a;
return gcd(b,a%b);
}
//考虑旋转:枚举旋转角度360/n*i,(0 t*i%n=0 => t=LCM(i,n)/i=n*i/GCD(n,i)/i=n/GCD(n,i)。
//那么可以上n/t种颜色,即n/(n/GCD(n,i))种,所以旋转的着色方案有k^GCD(n,i)种
int main()
{
LL n,q,k;
while (~scanf("%lld%lld",&k,&n)&&k&&n)
{
LL ans=0;
for (int i=1; i<=n; i++)
{
LL tmp=gcd(n,i);
ans+=(LL)(pow(k,tmp*1.0));//位置不变时 所有的点都有k种情况
}
if (n%2==1)//判断t的奇偶
ans+=(LL)(n*pow(k,(n+1)/2));//奇数情况下 置换造成的情况数量相同
else//偶数情况时
{
ans+=(LL)((n/2)*pow(k,(n+2)/2.0));//对角线对称翻转
ans+=(LL)((n/2)*pow(k,n/2));//对边对称翻转
}
ans=ans/(2*n);
printf("%lld\n",ans);
}
return 0;
}
Color
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 11725 | Accepted: 3775 |
Description
Beads of N colors are connected together into a circular necklace of N beads (N<=1000000000). Your job is to calculate how many different kinds of the necklace can be produced. You should know that the necklace might not use up all the N colors, and the repetitions that are produced by rotation around the center of the circular necklace are all neglected.
You only need to output the answer module a given number P.
Input
The first line of the input is an integer X (X <= 3500) representing the number of test cases. The following X lines each contains two numbers N and P (1 <= N <= 1000000000, 1 <= P <= 30000), representing a test case.
Output
For each test case, output one line containing the answer.
Sample Input
5
1 30000
2 30000
3 30000
4 30000
5 30000
Sample Output
1
3
11
70
629
题目大意:
第一行给出 X 之后输入X组 N 和 P
求出 至多用N种(可以少于N) 考虑旋转 不考虑翻转 构成长度为 P 的项链的数量
【只有旋转 则用Burnside定理】
PS:因为数据太大 不能用gcd函数实现 所以用欧拉函数优化
借鉴了别人的博客...因为第一次写的时候没有优化 连样例都过不去
参考:https://www.cnblogs.com/DrunBee/archive/2012/09/10/2678819.html
https://blog.csdn.net/wsniyufang/article/details/6671122
放代码
#include
#include
#include
#include
#include
using namespace std;
//Polya定理 欧拉函数优化
//题目数据太大 不能用gcd
const int MAXN=1000000000;
int isprime[50001];
int prime[8001];
int num,n,p;
void getprime()//得到素数
{
num=0;
for(int i=2; i<=50000; i++)
if(!isprime[i])
{
prime[num++]=i;
for(int j=1; j*i<=50000; j++)
{
isprime[i*j]=1;
}
}
}
int euler(int x)//获得比n小的且与n互质的数的数目
{
int res=x;
for(int i=0; i1) res=res/x*(x-1);
return res;
}
int expmod(int a,int b,int mod)//每次做幂级数运算都要取模操作
{
int ret=1;
a=a%mod;
while(b>0)
{
if(b%2==1)
ret=(ret*a)%mod;
a=(a*a)%mod;//二分思想
b=b/2;
}
return ret;
}
int main()
{
int Case;
getprime();
scanf("%d",&Case);
while(Case--)
{
scanf("%d%d",&n,&p);
int ans=0,i;
for(i=1; i*i
以后如果做到此类题目 还会来更新的......