码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 2409 Let it Bead【Polya定理】(模板题)

时间:2018-08-11 20:51:05      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:let   .net   col   ace   ref   解决   ima   情况   namespace   

<题目链接>

题目大意:
用k种颜色对n个珠子构成的环上色,旋转、翻转后相同的只算一种,求不等价的着色方案数。

解题分析:

对于这种等价计数问题,可以用polay定理来解决,本题是一道polay定理的模板题。

具体polay定理的实现步骤如下(选自算法入门经典训练指南  147页):

技术分享图片

 

#include<iostream>
#include<stdio.h>
using namespace std;
typedef long long LL;
int n, m;

int gcd(int a, int b) {
    if (b == 0)return a;
    return gcd(b, a % b);
}

LL pow(LL a, LL b) {       //快速幂
    LL ans;
    for (ans = 1; b; b >>= 1) {
        if (b & 1)
            ans *= a;
        a *= a;
    }
    return ans;
}

int main() {
    int i, j;
    while (scanf("%d%d", &m, &n) ,n||m) 
    {
        LL ans = 0;

        //旋转的情况 
        for (i = 0; i < n; i++)
            ans = ans + pow((LL) m, (LL) gcd(n, i));

        //翻转的情况
        if (n & 1)
            ans += n * pow((LL) m, (LL) n / 2 + 1);            //若n为奇数,以一个顶点和另外一条边中点的连线为对称轴
        else
            ans += n / 2 * (pow((LL) m, (LL) n / 2) + pow((LL) m, (LL) n / 2 + 1)); //n为偶数时,以两个顶点连线为对称轴  和  以两个顶点之间的连线为对称轴的情况
        
        printf("%lld\n", ans /(2*n));       //(2*n)==n+n(n为奇数)或者是n+(n/2+n/2)
    }
    return 0;
}

 

 

2018-08-11

POJ 2409 Let it Bead【Polya定理】(模板题)

标签:let   .net   col   ace   ref   解决   ima   情况   namespace   

原文地址:https://www.cnblogs.com/00isok/p/9460870.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!