Arif in Dhaka (First Love Part 2)
Input: standard input
Output: standard output
Time Limit: 2 seconds
Our hero Arif is now in Dhaka (Look at problem 10244 – First Love if you want to know more about Arif, but that information is not necessary for this problem. In short, Arif is a brilliant programmer working at IBM) and he is looking for his first love. Days pass by but his destiny theory is not working anymore, which means that he is yet to meet his first love. He then decides to roam around Dhaka on a rickshaw (A slow vehicle pulled by human power), running DFS (by physical movement) and BFS (with his eyes) on every corner of the street and market places to increase his probability of reaching his goal. While roaming around Dhaka he discovers an interesting necklace shop. There he finds some interestingnecklace/bracelet construction sets. He decides to buy some of them, but his programmer mind starts looking for other problems. He wants to find out how many different necklace/bracelet can be made with a certain construction set. You are requested to help him again. The following things are true for a necklace/bracelet construction set.
a) All necklace/bracelet construction sets has a frame, which has N slots to place N beads.
b) All the slots must be filled to make a necklace/bracelet.
c) There are t types of beads in a set. N beads of each type are there in the box. So the total number of beads is tN (tmultiplied by N), of which exactly N can be used at a time.
Fig: Different types of necklace for t=2 and different value of N
The figure above shows necklaces for some different values of N (Here, t is always 2). Now let’s turn out attentions tobracelets. A bracelet is a necklace that can be turned over (A junior programmer in Bangladesh says that wrist watch is anecklace (Boys!!! Don’t mind :-))). So for a bracelet the following two arrangements are equivalent. Similarly, all other opposite orientation or mirror images are equivalent.
So, given the description of a necklace/bracelet construction set you will have to determine how many different necklace and bracelet can be formed with made with that set
Input
The input file contains several lines of input. Each line contains two positive integers N(0<N<51) and t(0<t<11) as described in the problem statement. Also note that within this input range inputs will be such that no final result will exceed11 digits. Input is terminated by end of file.
Output
For each line of input produce one line of output which contains two round numbers NN and NB separated by a single space, where NN is the number of total possible necklaces and NB is the number of total possible bracelets for the corresponding input set.
Sample Input
5 2
5 3
5 4
5 5
Sample Output
8 8
51 39
208 136
629 377
转:http://blog.csdn.net/keshuai19940722/article/details/38533165
首先,我们来看看两个很有用的关于置换的定理,第一个就是Burnside(烧边?)引理,描述为:对于置换f,一种着色方案s经过一种置换后不变,则成这种着色方案s是f的不动点。若将f的不动点计为C(f),则可以证明等价类数目为所有C(f)的平均值。
一般用这个引理就可以解决所有的问题了。
而Polya定理是这样给出的:如果置换f可以分解成m(f)个循环的乘积,那么每个循环内的颜色必须相同(必须的,不信则可以自己试验一下),假设有t中颜色,那么C(f)= t^(m(f)),则等价类数目也可求得、
而这个题目就是非常经典的置换的题目,只不过对于手镯来说,你就要注意手镯是可以旋转,也可以翻转的,所以最后是要加上旋转的数目,并且切记奇偶是不同的两种情况。
题目大意:项链和手镯都是由若珠子穿成的环形首饰,区别在于手镯可以翻转,但是项链不行。给定n和t,表示用t种颜色的n个珠子能制作的项链和手镯的个数。
解题思路:等价类计数,一共两种置换,旋转或者翻转。
- 旋转:枚举间距0,1,2,3…,n−1,所以不动点a=∑i=0n−1tgcd(n,i)
- 翻转:当n为奇数时,对称轴有n条,每条对称轴形成n−12个长度为2的循环和一个长度为1的循环,所以不动点b1=ntn+1/2;当n为偶数时,有两种对称轴,一种是穿过珠子的,一种是不穿过珠子的,都有n2条,但是形成的循环分别为n2−1个长度为2和两个长度为1,n2个长度为2,所以b2=n∗(tn/2+1+tn/2)2
#include <iostream>
#include <math.h>
using namespace std;
#define LL long long
LL n, t;
double p, q;
LL gcd(LL a, LL b)
{
return b == 0 ? a : gcd(b, a % b);
}
void polya()
{
for (LL i = 1; i <= n; i++)
p += pow(1.0 * t, gcd(i, n)); //旋转循环数,顺时针旋转i格
q = p;
if (n % 2 == 0)
{
q += n / 2 * pow(1.0 * t, n / 2) + n / 2 * pow(1.0 * t, n / 2 + 1); //翻转,点数为偶数,分为由经过点和没经过点
}
else
{
q += n * pow(1.0 * t, n / 2 + 1); //翻转,点个数为奇数时,对称线经过一个点
}
p = p / n;
q = q / (2 * n);
}
int main()
{
while (cin >> n >> t)
{
p = 0, q;
polya();
cout << (LL)p << " " << (LL)q << endl;
}
return 0;
}
// 循环数,以6格点为例,记点为 1,2,3,4,5,6
// 翻转1:以1,2中间点翻转:得到 2,1,6,5,4,3
// 其中1->2,2->1成一个循环,共三个
// 翻转2:经过1,4的对称线翻转: 1,6,5,4,3,2
//循环为(1)(2,6)(3,5)(4)四个
//旋转:最大公约数就是循环数
// 最后本质不同数(即旋转和翻转后一样的都不要)为1/|G|*(∑颜色数^旋转i循环数+∑颜色数^翻转循环数)
//其中|G|为变换的总数,旋转n种,翻转n种
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef unsigned long long ll;
const int maxn = 50;
int gcd (int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
int main () {
int n, t;
ll p[maxn];
while (scanf("%d%d", &n, &t) == 2) {
p[0] = 1;
for (int i = 1; i <= n; i++) {
p[i] = p[i-1] * t;
printf("%lld\n", p[i]);
}
ll a = 0, b = 0;
for (int i = 0; i < n; i++)
a += p[gcd(n, i)];
if (n&1)
b = n * p[(n+1)/2];
else
b = n / 2 * (p[n/2+1] + p[n/2]);
printf("%lld %lld\n", a / n, (a + b) / 2 / n);
}
return 0;
}