P4980 【模板】Polya定理
阿新 • • 發佈:2018-12-21
fine isp 染色 結果 pla 直接 只需要 for arp
P4980 【模板】Polya定理
題目描述
給定一個\(n\)個點,\(n\)條邊的環,有\(n\)種顏色,給每個頂點染色,問有多少種本質不同的染色方案,答案對\(10^9+7\)取模
註意本題的本質不同,定義為:只需要不能通過旋轉與別的染色方案相同。
輸入輸出格式
輸入格式:
第一行輸入一個\(t\),表示有\(t\)組數據
第二行開始,一共\(t\)行,每行一個整數\(n\),意思如題所示。
輸出格式:
共\(t\)行,每行一個數字,表示染色方案數對\(10^9+7\)取模後的結果
說明
\(n \leq 10^9,t \leq 10^3\)
註意置換只有\(n\)個,表示旋轉的度數,沒有翻轉。
那麽一個旋轉\(i\)個點的置換的循環個數應該為\(\gcd(i,m)\)
帶到\(Polya\)定理裏面去,方案數為
\[\frac{1}{n}\sum_{i=1}^n n^{\gcd(i,n)}\]
\[=\frac{1}{n}\sum_{i=1}^n n^k\sum_{k=1}^n[\gcd(i,n)=k]\]
\[=\frac{1}{n}\sum_{k\mid n} n^k\sum_{k=1}^n[\gcd(i,n)=k]\]
\[=\sum_{k\mid n} n^{k-1}\sum_{k=1}^{\frac{n}{k}}[\gcd(i,n)=1]\]
\[=\sum_{k|n}n^{k-1}\varphi(\frac{n}{k})\]
然後直接暴力搞,復雜度是常數很小的\(O(Tn^{\frac{3}{4}})\)
Code:
#include <cstdio> const int mod=1e9+7; int Euler(int n) { int phi=n; for(int i=2;i*i<=n;i++) if(n%i==0) { phi=phi-phi/i; while(n%i==0) n/=i; } if(n!=1) phi=phi-phi/n; return phi; } #define mul(a,b) (1ll*(a)*(b)%mod) #define add(a,b) ((a+b)%mod) int qp(int d,int k){int f=1;while(k){if(k&1)f=mul(f,d);d=mul(d,d),k>>=1;}return f;} int Polya(int n) { int ans=0; for(int i=1;i*i<=n;i++) { if(n%i) continue; ans=add(ans,mul(qp(n,i-1),Euler(n/i))); if(i*i!=n) ans=add(ans,mul(qp(n,n/i-1),Euler(i))); } return ans; } int main() { int n,T; scanf("%d",&T); while(T--) { scanf("%d",&n); printf("%d\n",Polya(n)); } return 0; }
2018.12.21
P4980 【模板】Polya定理