P4980 【模板】Pólya 定理

作为板子题,先上公式:

|X/G|=1|G|gG|B|c(g)

显然,|G|=n

gi 表示旋转 i 个的置换,则 c(gi)=(n,i)

我们要算下式:

1ni=1nn(n,i)=1ndnndi=1n[(n,i)=d]=1ndnndφ(nd)

本题中直接暴力计算 φ 可以通过。

分析复杂度可参见本文

复杂度 O(Tn34)

或者考虑利用该博客中的法二计算。

但考虑到实际上 d(n) 远小于 n(当 n 足够大时,d(n)logn 也小于 n),所以法二的单次复杂度就是 O(n) 的。

我的程序使用方法二,复杂度 O(Tn)

View Code
#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;
char buf[1<<14],*p1=buf,*p2=buf;
#define GetC() ((p1==p2)&&(p2=(p1=buf)+fread(buf,1,1<<14,stdin),p1==p2)?EOF:*p1++)
struct Ios{}io;
template <typename _tp>
Ios &operator >>(Ios &in,_tp &x){
	x=0;int w=0;char c=GetC();
	for(;!isdigit(c);w|=c=='-',c=GetC());
	for(;isdigit(c);x=x*10+(c^'0'),c=GetC());
	if(w) x=-x;
	return in;
}
const int mod=1e9+7,N=30;
using ll=long long;
ll qpow(ll a,int b){
	ll ans=1;
	while(b){
		if(b&1) ans=ans*a%mod;
		b=b>>1;a=a*a%mod;
	}
	return ans;
}
int q[N],num[N],cnt;
int ans,n;
void dfs(int stp,int d,int phi){
	if(stp>cnt){
		ans=(ans+qpow(n,n/d)*phi%mod)%mod;
		return ;
	}
	dfs(stp+1,d,phi);
	int t=1;
	for(int i=1;i<=num[stp];++i){
		dfs(stp+1,d*t*q[stp],phi*t*(q[stp]-1));
		t*=q[stp];
	}
}
int main(){
	int T;io>>T;
	while(T--){
		io>>n;
		cnt=0;
		int tmp=n;
		for(int i=2;1ll*i*i<=n;++i){
			if(n%i==0){
				q[++cnt]=i;
				num[cnt]=0;
				while(n%i==0) n/=i,++num[cnt];
			}
		}
		if(n>1){
			q[++cnt]=n;num[cnt]=1;
		}
		n=tmp;
		dfs(1,1,1);
		printf("%lld\n",(ll)ans*qpow(n,mod-2)%mod);
		ans=0;
	}
	return 0;
}
posted @   pref_ctrl27  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
点击右上角即可分享
微信分享提示