首页 > 代码库 > UVa 10294 Arif in Dhaka (First Love Part 2) Polya定理

UVa 10294 Arif in Dhaka (First Love Part 2) Polya定理

题目来源:UVa 10294 Arif in Dhaka (First Love Part 2)

题意:n颗珠子t种颜色 求有多少种项链和手镯 项链不可以翻转 手镯可以翻转

思路:Polya定理  题目就是求等价类 项链只能旋转 手镯可以旋转也可以翻转

根据定理 等价类的数量等于各个置换f的t^m(f)的平均数 m(f)是置换的循环节数 下面每次t^x x都是循环节数

下面考虑手镯 旋转翻转都算

对于旋转 可以旋转0,1,...,n-1 每一个置换的循环节为gcd(0,n), gcd(1,n), ..., gcd(n-1,n)

所以等价类为t^gcd(0,n) + t^gcd(1,n)+ ...+t^gcd(n-1,n) = a 设为a

t是输入的颜色数量 这里没有除以置换的数量 最后算完翻转在除

对于翻转 分奇数和偶数

奇数

翻转只能拿住一个点翻转 可以拿住n个点的任何一个 等价类为n*t^(n/2+1) = b 设为b 拿住的那一个点自己就是一个循环节 剩下的2个一组为循环节

偶数

可以拿住两个点 或者不拿 拿住2个点有n/2*t^(n/2+1) 拿住的两个点是2个为1的循环节 剩下的2个一组为循环节 n/2是去重 选的两个点连起来是对称轴

可以不拿 n/2*t^(n/2) 2个一组为循环节 n/2*(t^(n/2+1)+t^(n/2)) = b设为b

最后还要求平均数 除以所有置换的数量

旋转和翻转的置换数量为n+n=2n 答案为(a+b)/2/n

 


 

#include <cstdio>
#include <cstring>
typedef long long LL;
const int maxn = 55;
LL a[maxn];
LL gcd(LL a, LL b)
{
	return b ? gcd(b, a%b) : a;
}
int main()
{
	int n, m;
	while(scanf("%d %d", &n, &m) != EOF)
	{
		a[0] = 1;
		for(int i = 1; i <= n; i++)
		{
			a[i] = a[i-1] * m;
		}
		LL x = 0, y = 0;
		for(int i = 1; i <= n; i++)
		{
			x += a[gcd(i, n)];
		}
		if(n&1)
		{
			y = a[(n+1)/2]*n;
		}
		else
		{
			y = (a[n/2] + a[n/2+1])*n/2;
		}
		printf("%lld %lld\n", x/n, (x+y)/2/n);
	}
	return 0;
}