[BZOJ2818]Gcd(莫比乌斯反演)
2016-04-07 19:34
423 查看
题目描述
传送门题解
∑i=1n∑j=1n∑d=1prime[0][gcd(i,j)=prime[d]]=∑i=1n∑j=1n∑d=1prime[0][gcd(iprime[d],jprime[d])=1]
=∑d=1prime[0]∑i=1nprime[d]∑j=1nprime[d][gcd(i,j)=1]
=∑d=1prime[0]∑i=1nprime[d]∑j=1nprime[d]∑t|gcd(i,j)μ(t)
=∑d=1prime[0]∑i=1nprime[d]∑j=1nprime[d]∑t=1n[t|i][t|j]μ(t)
=∑d=1prime[0]∑t=1n∑i=1nprime[d][t|i]∑j=1nprime[d][t|j]μ(t)
=∑d=1prime[0]∑t=1nnprime[d]tnprime[d]tμ(t)
枚举质数是必须要枚举的,后面的那一坨根n分块,预处理mu的前缀和。
代码
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> using namespace std; #define LL long long const int max_n=1e7+5; LL n; LL ans; LL p[max_n],prime[max_n],mu[max_n]; inline void get_mu(int n){ mu[1]=1; for (int i=2;i<=n;++i){ if (!p[i]){ prime[++prime[0]]=i; mu[i]=-1; } for (int j=1;j<=prime[0]&&i*prime[j]<=n;++j){ p[i*prime[j]]=1; if (i%prime[j]==0){ mu[i*prime[j]]=0; break; } else mu[i*prime[j]]=-mu[i]; } mu[i]+=mu[i-1]; } } int main(){ scanf("%lld",&n); get_mu(n); LL j; for (LL d=1;d<=prime[0]&&prime[d]<=n;++d){ LL N=(LL)n/prime[d]; for (LL i=1;i<=N;i=j+1){ j=min(N,N/(N/i)); ans+=(N/i)*(N/i)*(mu[j]-mu[i-1]); } } printf("%lld\n",ans); }
相关文章推荐
- 61. Rotate List
- 方法和构造方法的区别。
- 第一周周记
- 深度优先搜索
- UVA 10294 poj 3270 置换问题
- SPI总线的特点、工作方式介绍
- hdu4975A simple Gaussian elimination problem.【网络流判断是否解唯一】
- 顺序结构存储串实现串通配符匹配的算法
- 剑指offer-面试题6.重建二叉树
- 第七周一周总结
- spring 配置文件中的占位符 使用 context:property-placeholder
- Java Script之创建对象
- 博弈论的总结
- 技术贴
- 功夫茶侠(品茗)
- UESTC第十四届校赛A题解题报告
- Manifest merger failed : Attribute application@label value=(@string/app_name)
- oracle数据库归档日志文件管理常用命令
- GDAL创建图像提示Driver xxx does not support XXX creation option的原因
- Java基础知识