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

<题目链接>

题目大意:
用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));      //注意这里不用乘以n

        //翻转的情况
        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

posted @ 2018-08-11 19:56  悠悠呦~  阅读(255)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end