题目来源:UVa 10294 Arif in Dhaka (First Love Part 2)
题意:n颗珠子t种颜色 求有多少种项链和手镯 项链不可以翻转 手镯可以翻转
思路:Polya定理 题目就是求等价类 项链只能旋转 手镯可以旋转也可以翻转
根据定理 等价类的数量等于各个置换f的t^m(f)的平均数 m(f)是置换的循环节数 下面每次t^x x都是循环节数
下面考虑手镯 旋转翻转都算
对于旋转 可以旋转0,1,...,n-1 每一个置换的循环节为gcd(0,n), gcd(1,n), ..., gcd(n-1,n)
所以等价类为t^gcd(0,n) + t^gcd(1,n)+ ...+t^gcd(n-1,n) = a 设为a
t是输入的颜色数量 这里没有除以置换的数量 最后算完翻转在除
对于翻转 分奇数和偶数
奇数
翻转只能拿住一个点翻转 可以拿住n个点的任何一个 等价类为n*t^(n/2+1) = b 设为b 拿住的那一个点自己就是一个循环节 剩下的2个一组为循环节
偶数
可以拿住两个点 或者不拿 拿住2个点有n/2*t^(n/2+1) 拿住的两个点是2个为1的循环节 剩下的2个一组为循环节 n/2是去重 选的两个点连起来是对称轴
可以不拿 n/2*t^(n/2) 2个一组为循环节 n/2*(t^(n/2+1)+t^(n/2)) = b设为b
最后还要求平均数 除以所有置换的数量
旋转和翻转的置换数量为n+n=2n 答案为(a+b)/2/n
#include <cstdio> #include <cstring> typedef long long LL; const int maxn = 55; LL a[maxn]; LL gcd(LL a, LL b) { return b ? gcd(b, a%b) : a; } int main() { int n, m; while(scanf("%d %d", &n, &m) != EOF) { a[0] = 1; for(int i = 1; i <= n; i++) { a[i] = a[i-1] * m; } LL x = 0, y = 0; for(int i = 1; i <= n; i++) { x += a[gcd(i, n)]; } if(n&1) { y = a[(n+1)/2]*n; } else { y = (a[n/2] + a[n/2+1])*n/2; } printf("%lld %lld\n", x/n, (x+y)/2/n); } return 0; }
UVa 10294 Arif in Dhaka (First Love Part 2) Polya定理,布布扣,bubuko.com
时间: 2024-10-12 21:37:32