其他分享
首页 > 其他分享> > #容斥,莫比乌斯函数#洛谷 2231 [HNOI2002]跳蚤

#容斥,莫比乌斯函数#洛谷 2231 [HNOI2002]跳蚤

作者:互联网

题目


分析

考虑公约数为\(x\)很好做,就是\(\lfloor\frac{m}{x}\rfloor^n\),
这可以用枚举约数实现容斥当然也可以用莫比乌斯函数,
答案也就是\(\sum_{d|m}\mu(d)(\frac{m}{d})^n\)


代码

#include <cstdio>
#include <cctype>
#include <map>
#define rr register
using namespace std;
typedef long long lll; map<lll,bool>uk;
lll n,nn,m,ans,Cnt,prime[31],pw[31];
inline void dfs(lll rest,lll now,lll mu,lll mul){
	if (uk[now]) return;
	ans+=mul*mu,uk[now]=1;
	if (now==n) return;
	for (rr int i=1;i<=Cnt;++i)
	if (rest%prime[i]==0){
		if (now%prime[i]==0) continue;
		    else dfs(rest/prime[i],now*prime[i],-mu,mul/pw[i]);
	}
}
inline lll ksm(lll x,lll y){
	rr lll ans=1;
	for (;y;y>>=1,x=x*x)
	    if (y&1) ans=ans*x;
	return ans;
}
signed main(){
	scanf("%lld%lld",&m,&n),nn=n;
	for (rr lll i=2;i*i<=nn;++i)
	if (nn%i==0){
		while (nn%i==0) nn/=i;
		prime[++Cnt]=i; 
	}
	if (nn>1) prime[++Cnt]=nn;
	for (rr int i=1;i<=Cnt;++i)
	    pw[i]=ksm(prime[i],m);
	dfs(n,1,1,ksm(n,m));
	return !printf("%lld",ans);
}

标签:include,洛谷,rr,2231,lll,容斥,ans,return,now
来源: https://www.cnblogs.com/Spare-No-Effort/p/14029256.html