POJ 2409 Let it Bad

R e s u l t Result Result

0.0.0


H y p e r l i n k Hyperlink Hyperlink

http://poj.org/problem?id=2409


D e s c r i p t i o n Description Description

一个长度为 n n n的环状项链,有 m m m种颜色,若一个项链通过翻转or旋转能和另一个相同,我们认为这两个串是相同的。问本质不同的串的数量(也可以看做本质不同的染色方案)

数据范围: n , m ≤ 32 n,m\leq 32 n,m32


S o l u t i o n Solution Solution

先考虑旋转这种置换,显然从第 k k k个位置断开的循环为 g c d ( k , n ) gcd(k,n) gcd(k,n)

再考虑翻转,实际上就是问正 n n n边形对称轴的个数以及相应的对称点个数,分 n n n的奇偶性讨论一下即可

最后要处于置换群数 2 n 2n 2n(旋转 n n n种,无论奇数偶数翻转的置换群数都是 n n n种)

时间复杂度: O ( n log ⁡ n ) O(n\log n) O(nlogn)


C o d e Code Code

#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
LL n,res,m;
inline LL read()
{
	char c;LL d=1,f=0;
	while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;
	while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
	return d*f;
}
inline LL ksm(LL x,LL y)
{
	LL res=1;
	for(;y;y>>=1,x*=x) if(y&1) res*=x;
	return res; 
}
inline LL gcd(LL x,LL y){return y?gcd(y,x%y):x;} 
signed main()
{
	while(m=read(),n=read(),n||m)
	{
		res=0;
		for(register int i=1;i<=n;i++) res+=ksm(m,gcd(n,i));
		if(n&1) res+=n*ksm(m,(n+1)/2);else res+=n/2*(ksm(m,n/2)+ksm(m,n/2+1)); 
		printf("%lld\n",res/2/n);
	} 
}
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页