<题目链接>
题目大意:
用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 ", ans /(2*n)); //(2*n)==n+n(n为奇数)或者是n+(n/2+n/2) } return 0; }
2018-08-11