poj 2409 Let it Bead【polya定理+burnside引理】

两种置换
旋转:有n种,分别是旋转1个2个……n个,旋转i的循环节数位gcd(i,n)
翻转:分奇偶,对于奇数个,只有一个珠子对一条边的中点,循环节数为n/2+1;对于偶数个,有珠子对珠子和边对边,循环节个数为n/2+1个和n/2个
然后用polya定理即可

#include<iostream>
#include<cstdio>
using namespace std;
long long n,k,ans;
long long ksm(long long a,long long b)
{
	long long r=1;
	while(b)
	{
		if(b&1)
			r=r*a;
		a=a*a;
		b>>=1;
	}
	return r;
}
long long gcd(long long a,long long b)
{
	return !b?a:gcd(b,a%b);
}
int main()
{
	while(scanf("%d%d",&k,&n)&&k+n)
	{
		ans=(n&1)?ksm(k,n/2+1)*n:ksm(k,n/2+1)*n/2+ksm(k,n/2)*n/2;
		for(int i=1;i<=n;i++)
			ans+=ksm(k,gcd(i,n));
		printf("%lld\n",ans/2/n);
	}
	return 0;
}
posted @ 2018-07-04 09:51  lokiii  阅读(196)  评论(0编辑  收藏  举报