把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

入门失败的Polya定理

前言

一脸懵逼。。。

\(Upt\):后来的我,终于入门成功了——重新入门的Polya定理

公式

\(m\)种颜色染色的本质不同的方案数:

\[\frac1{|G|}\sum_{g∈G}m^{c(g)} \]

其中\(c\)表示置换\(g\)中环的个数。

板子题(点此看题面

考虑本质不同只需要判旋转,因此共有\(n\)种置换方式,其中第\(i\)种置换方式就是将所有数移动\(i\)位。

显然,第\(i\)种置换中环的个数应该是\(gcd(i,n)\),因此得到答案的式子为:

\[\frac1n\sum_{i=1}^nn^{gcd(i,n)} \]

看到\(gcd\),自然而然想到莫比乌斯反演,于是套路地枚举\(gcd\)得到:

\[\frac1n\sum_{d|n}n^d\sum_{i=1}^{\frac nd}[gcd(i,\frac nd)=1] \]

其中,后半部分的式子显然就是\(\phi(\frac nd)\)

也就是:

\[\frac 1n\sum_{d|n}n^d\phi(\frac nd) \]

因此,我们枚举\(d\),然后暴力计算\(\phi(\frac nd)\),这道题就做完了。

代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define X 1000000007
using namespace std;
int n;I int QP(RI x,RI y) {RI t=1;W(y) y&1&&(t=1LL*t*x%X),x=1LL*x*x%X,y>>=1;return t;}
I int Phi(RI x)//暴力计算欧拉函数
{
	RI i,t=1;for(i=2;i*i<=x;++i) if(!(x%i)) {t*=i-1,x/=i;W(!(x%i)) t*=i,x/=i;}
	return x^1&&(t*=x-1),t;
}
int main()
{
	RI Tt,i,t;scanf("%d",&Tt);W(Tt--)
	{
		for(scanf("%d",&n),t=0,i=1;i*i<=n;++i) !(n%i)&&//枚举因数
			(t=(1LL*QP(n,i)*Phi(n/i)+t)%X,i^(n/i)&&(t=(1LL*QP(n,n/i)*Phi(i)+t)%X));//统计答案
		printf("%d\n",1LL*t*QP(n,X-2)%X);//乘上1/n
	}return 0;
}
posted @ 2020-06-08 21:06  TheLostWeak  阅读(136)  评论(0编辑  收藏  举报