跳转至

Polya定理

约 551 个字 27 行代码 预计阅读时间 2 分钟

G=\{π_1,π_2,π_3,...,π_k\}X=\{a_1,a_2,a_3,...,a_n\} 上一个置换群,

//置换的集合即为置换群

m 种颜色对 X 中的元素进行涂色,那么不同的涂色方案数为:

\frac{1}{|G|} * \sum\limits_{i=1}^{k} m^{C(π_i)}


例题

黑白两种颜色对下面的2*2方格进行染色,

如果允许方格可以绕中心点旋转, 问有多少种不同的着色方案数?

\begin{matrix}1&2\\3&4\end{matrix}


方格可以旋转 0°,90°,180°,270°.

所以群 G = \{0°,90°,180°,270°\} ,|G| = 4

G 中 所有的置换是

π_1 = (1)(2)(3)(4)

π_2 = (1234)

π_3 = (14)(23)

π_4 = (1432)

c(π_1) = 4 , c(π_2) = 1 , c(π_3) = 2 , c(π_4) = 1

带入 Polya定理

ans = \frac{1}{4}*(2^4+2^1+2^2+2^1) = 6


原理

当只有旋转的时候(顺时针或逆时针),

对于一个有 n 个元素的环,可顺时针或逆时针旋转几个位置,

由于至少有 n 个置换,

但是假设我顺时针旋转 k 个位置,他就等同于逆时针转动 n-k 个位置,

假设一个置换为:

G=\{π_0,π_1,π_2,...,π_{n-1}\}

这个时候可以证明

逆时针旋转 k 个位置时

π_k 的循环节数为 gcd(n,k)

且每个循环的长度为 L=n/gcd(n,k)


上面那个例题只考虑了旋转的情况

翻转

  • n 为奇数的时候,只有一种形式,

以顶点 i 与中心的连线为轴的翻转

π_i=\begin{matrix}...&i-1&i&i+1&...\\...&i+1&i&i-1&...\end{matrix}

n 个循环节数为 (n+1)/2 的置换

  • 当n为偶数时,有两种形式:

  • 以顶点 i 与中心的连线为轴的翻转

π_i=\begin{matrix}...&i-1&i&i+1&...\\...&i+1&i&i-1&...\end{matrix}

n/2 个循环节数为 n/2+1 的置换

  1. 以顶点 ii+1 的中点与中心的连线为轴翻转

π_i=\begin{matrix}...&i-1&i&i+1&...\\...&i+2&i+1&i&...\end{matrix}

n/2 个循环节数为 n/2 的置换

要特别注意 0 的情况,输出 0 即可。

由于旋转有 n 种置换,翻转也有 n 种置换,所以 |G|=2n


例题

rotate 旋转

reflection to the axis of symmetry 翻转

poj 1286 考虑旋转和翻转

poj 2409 考虑旋转和翻转

poj 2154 考虑旋转

typedef long long ll;
ll fast_power(ll base,ll exponent)
{
    ll result=1;
    while(exponent>0)
    {
        if(exponent&1)
            result=result*base;
        base=base*base;
        exponent>>=1;
    }
    return result;
}
ll polya(ll n,ll m)
{
    if(!n)
        return 0;
    ll sum=0;
    for(ll i=0;i<n;++i)
        sum+=fast_power(m,__gcd(n,i));
    if(n&1)
        sum+=n*fast_power(m,(n+1)/2);
    else
        sum+=n/2*(1ll+m)*fast_power(m,n/2);
    sum/=(2*n);
    return sum;
}