[UVA 10294] polya定理 可循环翻转项链手镯问题

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,n1,所以不动点a=i=0n1tgcd(n,i)
  • 翻转:当n为奇数时,对称轴有n条,每条对称轴形成n12个长度为2的循环和一个长度为1的循环,所以不动点b1=ntn+1/2;当n为偶数时,有两种对称轴,一种是穿过珠子的,一种是不穿过珠子的,都有n2条,但是形成的循环分别为n21个长度为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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值