P4980-[模板]Pólya定理

正题

题目链接:https://www.luogu.com.cn/problem/P4980


题目大意

(n)个物品图上(m)种颜色,求在可以旋转的情况下本质不同的涂色方案。


解题思路

既然是群论基本题就顺便写一下刚刚了解到的相关知识把(顺便消磨一下时间

一个群((G, imes ))定义为一个在运算( imes)下满足以下条件的集合

  1. 封闭性:若存在(a,bin G)那么有(a imes bin G)
  2. 交换律:若有(a,b,cin G)那么有((a imes b) imes c=a imes (b imes c))
  3. 单位元:群中(exists ein G)满足(forall xin G)都有(x imes e=x)
  4. 逆元:对于(forall xin G)都有一个唯一元素(yin G)(x imes y=e)

然后中间一些东西很多很杂这里不多说了,直接到置换部分。

一般来说规定置换第一行为((1,2,3...)),那么定义一个置换(sigma=(g_1,g_2,g_3,...))。如果一个置换作用与一个排列(a),一般写为(sigma(a)=b)的话,就有(b_i=a_{g_i})。需要注意的是对于一个置换两次后相当与使用了另一个置换。(也就是置换只能生效一次

然后就是( ext{Burnside})引理了,对于一个置换群(G),若(G)作用与一个集合(X)时,集合(X)中本质不同的元素个数为

[frac{1}{|G|}sum_{fin G}C(f) ]

其中(C(f))表示(X)的所有元素中对于置换(f)的不动点数量。

( ext{Polya})定理就是建立在( ext{Burnside})引理上的,对于一个置换(f),定义它的循环节数量为(T(f)),用(m)种颜色染色时方本质不同的染色方案数就是

[frac{1}{|G|}sum_{fin G}m^{T(f)} ]

也就是(m^{T(f)}=C(f)),这个很显然,因为每个循环节涂成一种颜色就是一个不动点。

回到这题的旋转来,我们可以将其视为(n)个不同的置换构成的一个置换群。对于旋转(i)步,它的循环节数量就是(gcd(n,i)),也就是我们要求

[frac{1}{n}sum_{i=0}^{n-1}m^{gcd(n,i)} ]

枚举一下(gcd(n,i))

[frac{1}{n}sum_{d|n}m^dsum_{i=1}^{frac{n}{d}}[gcd(frac{n}{d},i)==1] ]

哦对啊好像有(m=n)

[frac{1}{n}sum_{d|n}n^dvarphi(frac{n}{d})=sum_{d|n}n^{d-1}varphi(frac{n}{d}) ]

这个时间复杂度大概是(O(Tn^{frac{3}{4}}))的,但是因为约数个数远到不了(sqrt n)所以你可以把它视为常数比较大的(O(Tsqrt n))


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll P=1e9+7;
ll T,n,ans;
ll power(ll x,ll b){
    ll ans=1;
    while(b){
        if(b&1)ans=ans*x%P;
        x=x*x%P;b>>=1;
    }
    return ans;
}
ll phi(ll x){
    ll ans=x;
    for(ll i=2;i*i<=x;i++){
        if(x%i)continue;
        while(x%i==0)x/=i;
        ans=ans/i*(i-1);
    }
    if(x>1)ans=ans/x*(x-1);
    return ans;
}
ll calc(ll x)
{return phi(x)*power(n,n/x-1)%P;}
signed main()
{
    scanf("%lld",&T);
    while(T--){
        scanf("%lld",&n);ans=0;
        for(ll i=1;i*i<=n;i++){
            if(n%i)continue;
            ans=(ans+calc(i))%P;
            if(i*i!=n)ans=(ans+calc(n/i))%P;
        }
        printf("%lld
",ans);
    }
    return 0;   
}
原文地址:https://www.cnblogs.com/QuantAsk/p/14269213.html