SPOJ VLATTICE Visible Lattice Points 初入莫比乌斯
2015-07-30 11:55
148 查看
题意:求两个点(x,y,z)的连线不经过其他点有几个
解:即为求GCD(x,y,z)为1的点有几个
解一:因为x,y,z均在1~n内,所以可以用欧拉函数解出
解二:莫比乌斯反演
设f
为GCD(x,y,z)=n的个数
设F[b]为b|GCD(x,y,z)的个数,很明显F[b]=(n/i)*(n/i)*(n/i)
所以F
=sigema(b|n,f[b]);
f
=sigema(n|b,mu
,F
)
解:即为求GCD(x,y,z)为1的点有几个
解一:因为x,y,z均在1~n内,所以可以用欧拉函数解出
解二:莫比乌斯反演
设f
为GCD(x,y,z)=n的个数
设F[b]为b|GCD(x,y,z)的个数,很明显F[b]=(n/i)*(n/i)*(n/i)
所以F
=sigema(b|n,f[b]);
f
=sigema(n|b,mu
,F
)
#include <stdio.h> #include <string.h> const int maxn=1000005; int prime[maxn]; int num[maxn]; int mu[maxn]; void mobius() { memset(num,0,sizeof(num)); mu[1]=1; int all=0; for(int i=2;i<maxn;i++) { if(!num[i]) { prime[all++]=i; mu[i]=-1; } for(int j=0;j<all&&i*prime[j]<maxn;j++) { num[i*prime[j]]=1; if(i%prime[j]) mu[i*prime[j]]=-mu[i]; else { mu[i*prime[j]]=0; break; } } } return ; } int main() { int t; int n; long long sum; mobius(); while(scanf("%d",&t)!=-1) { while(t--) { sum=3; //x,y,z轴 scanf("%d",&n); for(int i=1;i<=n;i++) { sum+=(long long)mu[i]*(n/i)*(n/i)*((n/i)+3); //在面上的点,所以+3 } printf("%lld\n",sum); } } return 0; }
相关文章推荐
- js_BOM_05
- Java中equals和==的区别
- 三大数据库分页sql
- (转)Java中equals和==的区别
- 函数的默认形参
- 2015年华为面试用C语言编写一个求大数字阶乘算法的题目
- 最该跳槽的时间点和最热招的十大行业
- 关于映射网络驱动 网络存在问题不能连接的原因
- 如何在Git 里撤销(几乎)任何操作
- Lua脚本语言入门
- 【Android测试】【第六节】Monkey——认识和使用
- js_DOM_04
- Umeng强制更新
- #1141 : 二分·归并排序之逆序对
- android sdk下载地址
- 将word转换成PDF的方法介绍
- Unity3D Shader入门优秀博客(二)
- ModelImporter的使用、在代码中添加动画片段
- Unity4.5动画控制状态切换监听脚本
- Javaz之Spring