Polya 定理入门[Burnside引理,Polya定理,欧拉函数]
Posted zbr162
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Polya 定理入门[Burnside引理,Polya定理,欧拉函数]相关的知识,希望对你有一定的参考价值。
$这篇blog重点讨论Polya的应用, 更详细的证明请百度 .$
___
$Burnside引理$
$$L=\frac1|G|\sum_i=1^|G|D(a_i)$$
$L$: 本质不同的方案数.
$G$: 置换群集合.
$a_i$: 置换群中的第 $i$ 个置换.
$D(a_i)$: 进行 $a_i$ 这个置换, 状态不会变化的方案 数量.
该引理与下方内容没有太大关系, 可以暂时忽略.
___
$Problem$ 链接
有 $N$ 个石子围成一圈, 使用 $M$ 种颜色染色, 求有多少种本质不同的方案.
借此问题引入 $Polya定理$ $↓$
$Polya定理$
$$L=\frac1|G|\sum_i=1^|G|M^C(g_i)$$
先丢出公式.
这道题的 置换群 $G$: 转$0$次, 转$1$次 ...转 $N-1$ 次, (皆为顺时针转动).
若满足旋转 $k$ 个位置, 状态和原来相同, 那么 $i$ 位置颜色 等于 $(i+k)%N$ 位置颜色,
旋转 $t$ 次, 仍和原来位置相同, 即 $i$ 位置与 $(i+tk)%N$ 位置颜色相同,
则 $i$ 旋转 $t$ 个 $k$ 次, 一定能回到原来位置, 即可以无限旋转,
所以 $i$ 就与 所有 $(i+tk)%N$ 位置呈现一个封闭的 $\colorred循环节$.
设转了 $t$ 次后, 第一次回到 $i$ 位置, 则
$t * k=lcm(k, N)=\frack*Ngcd(k,N)$,
$\therefore t=\fracNgcd(k,N)$,
$t$ 为$\colorred循环节$长度, 则$\colorred循环节$数量为 $\fracNt=gcd(k,N)$.
公式中 颜色的数量为 $M$; 在 $g_i$ 置换下, 有 $C(g_i)$ 个 $\colorred循环节$.
此题中 $C(g_i)=gcd(k,N)$, $$\therefore Ans=L=\frac1N\sum_k=0^N-1M^gcd(k,N)$$
___
$拓展 1$
假如上题增加 $\colorred对称同构$, 则意味着 原先的两个不同方案 对称 时计为一个方案,
按 $N$ 的奇偶 分类讨论:
- $N$ 为奇数, 对称轴上有一个点, 循环节个数为 $\fracN+12$, 总共有 $N$ 个对称轴置换, 则对答案贡献为 $\fracNM^\fracN+122N$
最后的答案为 $$Ans=L=\frac12N(\sum_k=0^N-1M^gcd(k,N)+NM^\fracN+12)$$ $N$ 为偶数, 对称轴上可以没有点, 也可以有两个点, 两种对称轴都有 $\fracN2$ 种, 总共有 $N$ 个对称轴置换,
对称轴上无点时, 循环节个数为$\fracN2$, 对答案贡献为 $\fracM^\fracN22N$,总贡献为$\frac\fracN2M^\fracN22N$.
对称轴上有点时, 循环节个数为$\fracN2+1$, 对答案贡献为 $\fracM^\fracN2+12N$, 总贡献为 $\frac\fracN2M^\fracN2+12N$.所以最后的答案为
$$Ans=L=\frac12N(\sum_k=0^N-1M^gcd(k,N)+\fracN2M^\fracN2+\fracN2M^\fracN2+1)$$
___
$拓展2$
若 $\colorredN<=10^9$ , $O(N)$计算下式会 $TLE$, 需要更快的办法,
$$Ans=L=\frac1N\sum_k=0^N-1M^gcd(k,N)$$
由于 $gcd(k,N)|N$, 而$N$的约数不会超过 $2\sqrtN$ 个,
考虑枚举 $d$, $(d|N)$
则就只需统计 $gcd(k,N)=d$ 的 $k$ 的个数.
$d=gcd(k,N)=gcd(dt, d\fracNd)$
则 $t$ 与 $\fracNd$ 互质, 即 $\colorredgcd(t, \fracNd) = 1$.
$\therefore \colorred\varphi(\fracNd)$ 即为 $gcd(k,N)=d$ 的 $k$ 的个数.
于是 $$Ans=L=\frac1N\sum_d|N\varphi(\fracNd) *M^d$$
.
$如何求解 \varphi(x)?$
根据定义: $$\varphi(x)=x\prod_p_i|x(1-\frac1p_i)$$
通分得: $\varphi(x) = x\prod_p_i|x\fracp_i-1p_i$
按上式实现, 时间复杂度小于 $O(\sqrtN)$, 均摊 $O(logN)?$
这里给出求解函数,
int Get_phi(int x)
int s = x;
for(int i = 2; i*i <= x; i ++)
if(x % i == 0) //找到一个质因数
s = s/i*(i-1);
while(x%i == 0) x /= i;
if(x > 1) s = s/x*(x-1); //不可能出现两个大于 sqrt(N) 的质因数, 所以只可能剩下一个, 处理掉就好 .
return s;
所以 $O(\sqrtN),O(logN)$ 分别求出所有约数 $d$ 和 $\varphi(\fracNd)$ 即可, 时间复杂度 $O(\sqrtNlogN)$.
___
$\mathcalCode$
#include<bits/stdc++.h>
#define reg register
const int mod = 1e9 + 7;
int T;
int N;
int phi(int x)
int s = x;
for(reg int i = 2; i*i <= x; i ++)
if(x % i == 0)
s = s/i * (i-1);
while(x % i == 0) x /= i;
if(x > 1) s = s/x * (x-1);
return s;
int KSM(int a, int b)
int s = 1; a %= mod;
while(b)
if(b & 1) s = 1ll*s*a % mod;
a = 1ll*a*a % mod, b >>= 1;
return s;
void Work()
scanf("%d", &N);
int Ans = 0;
int lim = sqrt(N);
for(reg int d = 1; d <= lim; d ++)
if(N % d) continue ;
Ans = ( 1ll*Ans + (1ll*phi(N/d) * KSM(N, d) % mod) ) % mod;
int d_2 = N / d;
if(d_2 == d) continue ;
Ans = ( 1ll*Ans + (1ll*phi(N/d_2) * KSM(N, d_2) % mod) ) % mod;
printf("%d\n", (1ll*Ans*KSM(N, mod-2)) % mod);
int main()
scanf("%d", &T);
while(T --) Work();
return 0;
$例题$
更多例题请戳 这里 .
以上是关于Polya 定理入门[Burnside引理,Polya定理,欧拉函数]的主要内容,如果未能解决你的问题,请参考以下文章