《算法竞赛-训练指南》-第二章-2.18_UVa 10294

本文深入探讨了一道经典的数学问题——构造不同类型的项链与手镯。通过运用置换理论中的Burnside引理和Polya定理,详细解析了如何计算不同颜色珠子构成的项链和手镯的数量。特别关注手镯的旋转和翻转特性,展示了数学在日常生活问题中的巧妙应用。
摘要由CSDN通过智能技术生成

非常的喜欢这道题目!


首先还是老规矩,描述一下这道题目,题目是这个意思:项链和手镯,都是有若干个珠子串成的,不同之处在于项链不能够反转,而手镯可以反转,而给你n个珠子,t中颜色,每种颜色可以是任意多个珠子,问你,可以构造出多少种项链和手镯!

这道题目,我私自认为是一道关于置换方面的经典的例题!开始我都没沉下心来去考虑这个题目,觉得不好玩,但是,当我沉下心仔细去考虑这道题目的时候,我真的觉得数学博大精深!

首先,我们来看看两个很有用的关于置换的定理,第一个就是Burnside(烧边?)引理,描述为:对于置换f,一种着色方案s经过一种置换后不变,则成这种着色方案s是f的不动点。若将f的不动点计为C(f),则可以证明等价类数目为所有C(f)的平均值。

一般用这个引理就可以解决所有的问题了。

而Polya定理是这样给出的:如果置换f可以分解成m(f)个循环的乘积,那么每个循环内的颜色必须相同(必须的,不信则可以自己试验一下),假设有t中颜色,那么C(f)= t^(m(f)),则等价类数目也可求得、

而这个题目就是非常经典的置换的题目,只不过对于手镯来说,你就要注意手镯是可以旋转,也可以翻转的,所以最后是要加上旋转的数目,并且切记奇偶是不同的两种情况。

贴出代码:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>

using namespace std;

typedef long long LL;

const int MAXN = 55;

LL pow_t[MAXN];

void init(int t)
{
	pow_t[0] = 1;
	for (int i = 1; i < MAXN; i++)
	{
		pow_t[i] = pow_t[i - 1] * t;
	}
}

int gcd(int a, int b)
{
	return b == 0 ? a : gcd(b, a % b);
}
int main()
{
	int n, t;
	while (scanf("%d%d", &n, &t) != EOF)
	{
		init(t);
		LL ans1 = 0;
		for (int i = 0; i < n; i++)
		{
			ans1 += pow_t[gcd(i, n)];
		}
		LL ans2 = 0;
		if (n % 2 == 0)
		{
			ans2 = n / 2 * (pow_t[(n + 2) / 2] + pow_t[n / 2]);	
		}
		else
		{
			ans2 = n * pow_t[(n + 1) / 2];
		}
		printf("%lld %lld\n", ans1 / n, (ans1 + ans2) / (2 * n));
		
	}
//	system("pause");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值