Polya定理
本篇文章並不是詳細講解,而是加深自己的記憶
群:
群的定義: 集合 \(G\) 和作用於集合 \(G\) 的二元計算 \(×\),滿足以下 \(4\) 個性質就記為 \((G,×)\)。
- 封閉性:\(a,b∈G\), \(a × b∈G\)
- 結合律:$ (a\times b)\times c = a\times (b\times c)$
- 單位元: 存在 \(e∈G\) ,滿足對於任意 \(a\in G\) 有: \(a\times e = e\times a = a\) ,此時 \(e\) 被稱為單位圓。乘法運算就是一個群。
- 逆元:對於任意 \(a\in G\) 存在 \(a'\in G\) 滿足 \(a\times a' = a'\times a = e\) ,此時 \(a'\) 唯一。
子群:
分為左陪集,右陪集。
陪集性質:
- \(\forall g\in G,|H|= |Hg|\)
- \(∀g∈G,g\in Hg\)
- \(Hg = H\iff g\in H\)
- \(Ha=Hb⟺a×b^{−1}∈H\)
- \(Ha∩Hb\neq∅→Ha=Hb\)
- \(H\) 的全體右陪集的並為 \(G\)
左陪集同理,證明省略2。
比較常見的表述:
若 \(H≤G\),則 \(G/H\) 代表 \(G\) 中所有的 \(H\) 的左陪集即 \(\{gH,g\in G\}\)
若 \(H≤G\),則 \([G:H]\) 表示 \(G\) 中 \(H\) 的不同的陪集的數量
拉格朗日定理:
置換:
定義:
雙行表示 \(\sigma\) 法:表示從上列 \(a\) 到下列 \(b\) 的置換,表示用第 \(a_i\) 個元素替換第 \(b_i\) 個元素。
表示一個置換
每個置換就是一個這樣的排列,一個長度為 \(n\) 的不同的置換數量為 \(n!\).
運算:
表示為 \(\sigma(a)\),運算規則為: \(\sigma(a)=(a_{\sigma1},a_{\sigma2}...a_{\sigma n})\)
我們稱呼為置換的合成。
置換群:
我們令群 \(G=(M,×)\) ,其中 \(M\) 為 \(N={1,2,3...n}\) 集合的若干個排列構成的集合,此時若 \(G\) 滿足群的性質,\(G\) 就是一個置換群。
群作用:
分為左群作用和右群作用:
對於一個集合 \(M\) 和群 \(G\):
若給定了一個二元函數 \(\phi(v,k)\) ,其中 \(v\) 為群中的元素, \(k\) 為集合元素,有:
其中 \(e\) 為單位元,則群 \(G\) 作用於集合 \(M\).
軌道-穩定子定理
Burnside 定理
定義 \(G\) 為一個置換群,定義其作用於 \(X\), 如果 \(x,y\in X\) 在 \(G\) 作用下可以相等,即存在 \(f\in G\) 使得 \(f(x)=y\) ,則定義 \(x,y\) 屬於一個等價類,則不同的等價類的數量為:
\(X^g\) 為 \(X\) 在 \(g\) 作用下的不動點的數量,即滿足 \(g(x)=x\) 這樣的 \(x\) 的數量。
文字版:\(X\) 在群 \(G\) 作用下的等價類總數等於每一個 \(g\) 作用於 \(X\) 的不動點的算數平均值。
綜上,就得到了 \(Burnside\) 定理。
本質不同的 \(n\) 個點的環可以看作:
在群 \(G\) 為 { 旋轉 \(0\) 個,旋轉 \(1\) 個...旋轉 \(n−1\) 個 } 這些置換作用下得到的等價類的數量。
同時我們定義集合 \(M\) 為 \(\{1\to n\}\) 的所有可能排列表示初始的環。
答案就為:
旋轉 \(0\) 個的不動點為 \(n^n\) ,即所有集合都合法。
對於旋轉 \(k\) 個,\(gcd(k,n)\) 隨意取,貢獻為 \(n^{gcd(k,n)}\)
答案就是:
枚舉 \(gcd\) ,再運用歐拉函數,得到:
暴力計算即可算出。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mod=1e9+7;
int T,n;
int qmi(int a,int b){
int res=1; while(b){if(b&1) res=res*a%mod; a=a*a%mod; b>>=1;} return res;
}
int phi(int x){
int ans=x;
for(int i=2;i<=sqrt(x);i++){
if(x%i) continue;
ans=ans-ans/i;
while(x%i==0) x/=i;
}
if(x!=1) ans=ans-ans/x;
return ans;
}
signed main(){
cin>>T;
while(T--){
cin>>n; int cnt=sqrt(n),ans=0;
for(int i=1;i<=cnt;i++){
if(n%i) continue;
int p1=phi(i),f1=qmi(n,n/i);
f1=f1*p1%mod; ans=(ans+f1)%mod;
if(i*i!=n){
int p2=phi(n/i),f2=qmi(n,i);
f2=f2*p2%mod; ans=(ans+f2)%mod;
}
}
cout<<ans*qmi(n,mod-2)%mod<<endl;
}
system("pause");
return 0;
}