polya定理
设有\(n\)个对象,\(G\)是这\(n\)个对象上的置换群,用\(m\)种颜色涂染着\(n\)个对象,每个对象涂一种颜色,问有多少种染色方案
\(G = {\sigma_1,\sigma_2,\dots,\sigma_k}\),\(c(\sigma_i)\)为置换\(\sigma_i\)的循环节数
群
集合\(G\)和\(G\)上的二元运算,满足下列条件称为群:
- 封闭性
- 结合律
- 有单位元
- 有逆元
置换群
\([1,n]\)到自身\(1-1\)映射称为\(n\)阶置换。\([1,n]\)目标集上的置换表示为
即\(a_n\)是\([1,n]\)中元的一个排列
举个例子,这是个\(n = 5\)的5元置换,\(\sigma(1) = 3,\sigma(3) = 1\),构成循环,\(\sigma(4) = 4\),4的置换是本身,也是一个循环,所以也可以写成\(\sigma = (1,3)(4)(2,5)\),一般一阶轮换(4)不写,\(\sigma = (1,3)(2.5)\)
正三角形
![114E8C20-99B6-41DB-988E-F314FA43C464](/Users/i/Library/Containers/com.tencent.qq/Data/Library/Application Support/QQ/Users/2287697454/QQ/Temp.db/114E8C20-99B6-41DB-988E-F314FA43C464.png)
旋转0°:\(p1 = \begin{array}{l} \left(\begin{array}{l} 1&2&3\\ 1&2&3 \end{array}\right) \end{array}\)
旋转120°:\(p2 = \begin{array}{l} \left(\begin{array}{l} 1&2&3\\ 2&3&1 \end{array}\right) \end{array}\)
旋转240°:\(p3 = \begin{array}{l} \left(\begin{array}{l} 1&2&3\\ 3&1&2 \end{array}\right) \end{array}\)
对称:\(p4 = \begin{array}{l} \left(\begin{array}{l} 1&2&3\\ 1&3&2 \end{array}\right) \end{array}\)\(p5 = \begin{array}{l} \left(\begin{array}{l} 1&2&3\\ 3&2&1 \end{array}\right) \end{array}\)\(p6 = \begin{array}{l} \left(\begin{array}{l} 1&2&3\\ 2&1&3 \end{array}\right) \end{array}\)
正四边形
旋转0°:\(p1 = \begin{array}{l} \left(\begin{array}{l} 1&2&3 &4\\ 1&2&3&4 \end{array}\right) \end{array}\)
旋转90°:\(p2 = \begin{array}{l} \left(\begin{array}{l} 1&2&3&4\\ 4&1&2&3 \end{array}\right) \end{array}\)
旋转180°:\(p3 = \begin{array}{l} \left(\begin{array}{l} 1&2&3&4\\ 3&4&1&2 \end{array}\right) \end{array}\)
旋转270°:\(p4 = \begin{array}{l} \left(\begin{array}{l} 1&2&3&4\\ 2&3&4&1 \end{array}\right) \end{array}\)
对称:\(p5 = \begin{array}{l} \left(\begin{array}{l} 1&2&3&4\\ 1&4&3&2 \end{array}\right) \end{array}\)\(p6 = \begin{array}{l} \left(\begin{array}{l} 1&2&3&4\\ 3&2&1&4 \end{array}\right) \end{array}\)\(p7 = \begin{array}{l} \left(\begin{array}{l} 1&2&3&4\\ 2&1&4&3 \end{array}\right) \end{array}\)\(p8 = \begin{array}{l} \left(\begin{array}{l} 1&2&3&4\\ 4&3&2&1 \end{array}\right) \end{array}\)
旋转0°:\((1)(2)(3)(4)(5)(6)(7)(8)(9)(10)(11)(12)(13)(14)(15)(16)\)
旋转90°:\((1)(2\ 3\ 4\ 5)(6\ 7)(8\ 9\ 10\ 11)(12\ 13\ 14\ 15)(16)\)
旋转180°:\((1)(2\ 4)(3\ 5)(6)(7)(8\ 10)(9\ 11)(12\ 14)(13\ 15)(16)\)
旋转270°:\((1)(2\ 3\ 4\ 5)(6\ 7)(8\ 9\ 10\ 11)(12\ 13\ 14\ 15)(16)\)
\(l = \frac{16 + 2 + 4 + 2}{4} =\)
Bunruside引理
等价类
k阶不动置换类
\(G\)是\(1,2,\dots ,n\)的置换群,\(k\)是\(1\dots n\)中的某个元素,\(G\)中使\(k\)保持不变的置换的全体,极为\(Z_k\)
Polya置换
设\(N = {1,2,\dots, n}\)是被着色物体的集合,\(G = {\sigma_1,\sigma_2,\dots,\sigma_g}\)是\(N\)上的置换群,用\(m\)种颜色对\(N\)中的元素进行着色,则在\(G\)的作用下不同的着色方案数是
其中\(G = {\sigma_1,\sigma_2,\dots,\sigma_k}\),\(c(\sigma_i)\)为置换\(\sigma_i\)的循环节数,即轮换个数,\(|G|\)表示置换种数
关键在于找到每个置换的循环节即可
对于这个置换
循环节是(1,3)(2,5)(4),所以循环节长度是3
利用polya定理
- 写出置换群
- 求出每个置换的轮换个数
- 带入公式求
写出有置换群
求出每个置换的轮换个数
\(c_1 = (1)(2)(3)(4)(5)(6)=6, \ c_2 = (1,2,3,4,5,6) = 1,c_3 = (1,3,5)(2,4,6) = 2,\\ c_4 = (1,4)(2,5)(3,6) = 3,c_5 = (1,3,5)(2,4,6) = 2,c_6 = (1,2,3,4,5) = 1\)
带入公式,用2种颜色去染色
\(M= \frac{2^6+2^1+2^2+2^3+2^2+2^1}{6} = 14\)
常见置换的轮换个数
旋转
n个点顺时针(或逆时针)旋转i个位置的置换,轮换个数是\(gcd(n,i)\)
假设旋转i个单位,使得与原来重合,设执行k次,那么一定满足\(i * k \mod n == 0\),那么解得最小\(k = \frac{lcm(i, n)}{i} = \frac{n}{gcd(n, i)}\),所以\(\frac{n}{k} = gcd(n,i)\)
翻转
n为偶数且对称轴不过顶点,轮换个数为\(\frac{n}{2}\)
n为偶数且对称轴过顶点,轮换个数为\(\frac{n}{2} + 1\)
n为奇数,轮换个数为\(\frac{n + 1}{2}\)
模板
对于翻转,如果n为奇数,找个对称轴经过点,一共有n条对称轴,每条对称轴上有一个点,对称轴上的珠子构成了一个循环,其他\(n-1\)个珠子分别与对称轴对此构造成\(\frac{n - 1}{2}\)个循环,所以循环节个数是\(\frac{n - 1}{2} + 1 = \frac{n + 1}{2}\)
如果n是偶数,对称轴上有两个点,一个有\(\frac{n}{2}\)条,对称轴上的两个点构成两个循环,其他\(n - 2\)个点分别以对称轴对此构成\(\frac{n - 2}{2}\)个循环。还有一种情况,对此轴穿过两个点之间,这时其他点两两对称,构成\(\frac{n}{2}\)个对称
对称有n个置换,旋转有n个置换,总共2n个置换
时间复杂度\(O(nlogn)\)
#include <iostream>
#include <cstdio>
#define ll long long
int gcd(int a, int b){
return b == 0 ? a : gcd(b, a % b);
}
ll pow(ll a, ll b){
ll ans = 1;
while(b){
if(b & 1) ans = ans * a;
a = a * a;
b >>= 1;
}
return ans;
}
int main(){
int n, m;
while(~scanf("%d%d", &m, &n)){
if(n == 0 && m == 0)break;
ll ans = 0;
for(int i = 1; i <= n; i++){
ans += pow(m, gcd(i, n));
}
if(n & 1){
ans += pow(m, n / 2 + 1) * n;
}else{
ans += pow(m, n / 2 + 1) * (n / 2);
ans += pow(m, n / 2) * (n / 2);
}
printf("%lld\n", ans / (2 * n));
}
return 0;
}
在旋转部分进行优化,\(\sum_{i = 1}^n n^{gcd(i,n)}\)
\(\sum_{d|n}n^d\times\sum_{k = 1}^{\frac{n}{d}}[gcd(k,\frac{n}{d}) == 1]\)
\(\sum_{d|n}n^d\varphi(\frac{n}{d})\)
时间复杂度\(O(n^{\frac{3}{4}})\)
#include <iostream>
#include <cstdio>
#include <cmath>
#define ll long long
using namespace std ;
const int mod = 1e9 + 7 ;
ll pow(ll a, ll b, ll p){
ll ans = 1; a %= p;
while(b){
if(b & 1) ans = ans * a % p;
a = a * a % p;
b >>= 1;
}
return ans;
}
ll phi(ll n) {
ll ans = n;
for(int i = 2; i * i <= n; ++ i ) {
if(n % i == 0){
ans -= ans / i;
while(n % i == 0) n /= i;
}
}
if(n > 1) ans -= ans / n ;
return ans ;
}
int main(){
int T, n, cnt;
scanf("%d", &T);
while( T-- ) {
scanf("%d", &n);
ll ans = 0;
for(int i = 1; i * i <= n; i++) {
if(n % i) continue;
ll p1 = phi(i), f1 = pow(n, n / i, mod);
f1 = f1 * p1 % mod; ans = (ans + f1) % mod;
if(i * i != n) {
ll p2 = phi(n / i), f2 = pow(n, i, mod) ;
f2 = f2 * p2 % mod; ans = (ans + f2) % mod;
}
}
printf("%lld\n", ans * pow(n, mod - 2, mod) % mod);
}
return 0 ;
}
原文地址:https://www.cnblogs.com/Emcikem/p/13282509.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 线程应用 - 中断interrupt详解
- ThreadLocal全面解析
- tomcat类加载机制了解一下
- tomcat-超详细的启动流程(init)
- tomcat-超详细的启动流程(start)
- NIO学习(一)Buffer缓冲区
- NIO学习(二)Channel通道与Selectors选择器
- Spring学习(一)bean的初始化过程
- Spring学习(二)bean的循环依赖
- Spring学习(三)后置处理器BeanPostProcessor
- Spring学习(四)AOP基础
- Spring知识点(五)代理模式
- Spring知识点(六)bean的生命周期
- Mybatis源码学习(一)SqlSessionFactoryBuilder
- 小程序工具初探