poj-2409 Let it Bead

75 篇文章 0 订阅
30 篇文章 0 订阅

题意:

给出c种颜色和s个珠子;

将珠子染色后穿成一个环;

旋转和翻转相同的视为同构;

求方案数;


题解:

polya计数的裸题;

定义m为颜色数,c(Pi)为Pi这个置换的循环节个数;

那么根据定理,答案L为;


然后只要求出各个置换的循环节就好了;

题中允许两种置换,先考虑旋转;

旋转有n种置换方式,分别是转0,转360/n,转2*360/n......转(n-1)*360/n;

每种的循环节数实际上是gcd,然后带入求和式;

然后考虑翻转,有奇偶的讨论;

奇数可以过每个珠子做对称轴,那么置换数就是n,循环节数都是n/2+1;

偶数可以过两个对角的珠子做对称轴,置换数是n/2,循环节数是n/2+1(其他的珠子除以2,加上轴上的两个);

也可以不过珠子,这样的置换数同样是n/2,循环节数是n/2了;

然后除个2*n就结束了;


代码:


#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 110000
using namespace std;
typedef long long ll;
int gcd(int a,int b)
{
	int t=a%b;
	while(t)
	{
		a=b,b=t;
		t=a%b;
	}
	return b;
}
int pow(int x,int y)
{
	int ret=1;
	while(y)
	{
		if(y&1)
			ret*=x;
		x*=x;
		y>>=1;
	}
	return ret;
}
int main()
{
	int n,m,i,j,k;
	while(scanf("%d%d",&m,&n)&&(n||m))
	{
		for(i=1,k=0;i<=n;i++)
			k+=pow(m,gcd(n,i));
		if(n&1)
			k+=n*pow(m,n/2+1);
		else
			k+=n/2*pow(m,n/2)+n/2*pow(m,n/2+1);
		k/=2*n;
		printf("%d\n",k);
	}
	return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值