【莫比乌斯反演】[SPOJ VLATTICE]Visible Lattice Points
2016-01-27 01:55
288 查看
题目描述:
Consider a N*N*N lattice. One corner is at (0,0,0) and the opposite one is at (N,N,N). How many lattice points are visible from corner at (0,0,0) ? A point X is visible from point Y iff no other lattice point lies on the segment joining X and Y.
大概就是给你个边长为n的立方体其中含有(n+1)3(n+1)^3个格点,那么如果当前位于(0,0,0)请问可以直接看到的格点有多少个?
题目分析首先可以把整个立体图形划分成三种第一种在经过(0,0,0)以下称为AA点
经过AA的棱上的
经过AA的面但是不包含1的
在AA的体内的但是不包含1、2的
显然就是把整个图形分成了三个(n*n)的面和一个(n*n*n)的立方体和三条棱,对于三条棱来说答案一定是3
对于n*n的平面来说如果一个点的横坐标和纵坐标互质那么这样的点的个数*3就是我们需要的三个面的点数的贡献首先F(i)=∑i|df(d)=⌊ni⌋2F(i)=\sum_{i|d}f(d)=\lfloor \frac{n}{i}\rfloor^2这里F(i)F(i)表示在i|gcd(a,b)i|gcd(a,b)这样的数对的个数f(i)f(i)表示i=gcd(a,b)i=gcd(a,b)的个数那么刚刚的式子显然成立,根据莫比乌斯反演可以得到f(i)=∑i|dμ(di)F(d)=∑i|dμ(di)⌊nd⌋2f(i)=\sum_{i|d}\mu(\frac{d}{i})F(d)=\sum_{i|d}\mu(\frac{d}{i})\lfloor \frac{n}{d}\rfloor^2那么显然此时i=1因为我们要求的就是(a,b)互质对的个数,那么另i=1就可以开始写程序了注意到⌊nd⌋\lfloor \frac{n}{d}\rfloor的取值范围有n−−√\sqrt{n}个那么可以稍微剪枝一下,同理可以得到另一个对于(a,b,c)来说两两互质的对数g(n)=∑i|dμ(di)⌊nd⌋3g(n)=\sum_{i|d}\mu(\frac{d}{i})\lfloor \frac{n}{d} \rfloor^3那么答案就是Ans=g(n)+3×f(n)+3Ans=g(n)+3\times f(n)+3
Consider a N*N*N lattice. One corner is at (0,0,0) and the opposite one is at (N,N,N). How many lattice points are visible from corner at (0,0,0) ? A point X is visible from point Y iff no other lattice point lies on the segment joining X and Y.
大概就是给你个边长为n的立方体其中含有(n+1)3(n+1)^3个格点,那么如果当前位于(0,0,0)请问可以直接看到的格点有多少个?
题目分析首先可以把整个立体图形划分成三种第一种在经过(0,0,0)以下称为AA点
经过AA的棱上的
经过AA的面但是不包含1的
在AA的体内的但是不包含1、2的
显然就是把整个图形分成了三个(n*n)的面和一个(n*n*n)的立方体和三条棱,对于三条棱来说答案一定是3
对于n*n的平面来说如果一个点的横坐标和纵坐标互质那么这样的点的个数*3就是我们需要的三个面的点数的贡献首先F(i)=∑i|df(d)=⌊ni⌋2F(i)=\sum_{i|d}f(d)=\lfloor \frac{n}{i}\rfloor^2这里F(i)F(i)表示在i|gcd(a,b)i|gcd(a,b)这样的数对的个数f(i)f(i)表示i=gcd(a,b)i=gcd(a,b)的个数那么刚刚的式子显然成立,根据莫比乌斯反演可以得到f(i)=∑i|dμ(di)F(d)=∑i|dμ(di)⌊nd⌋2f(i)=\sum_{i|d}\mu(\frac{d}{i})F(d)=\sum_{i|d}\mu(\frac{d}{i})\lfloor \frac{n}{d}\rfloor^2那么显然此时i=1因为我们要求的就是(a,b)互质对的个数,那么另i=1就可以开始写程序了注意到⌊nd⌋\lfloor \frac{n}{d}\rfloor的取值范围有n−−√\sqrt{n}个那么可以稍微剪枝一下,同理可以得到另一个对于(a,b,c)来说两两互质的对数g(n)=∑i|dμ(di)⌊nd⌋3g(n)=\sum_{i|d}\mu(\frac{d}{i})\lfloor \frac{n}{d} \rfloor^3那么答案就是Ans=g(n)+3×f(n)+3Ans=g(n)+3\times f(n)+3
[code]#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std; const long long MAXN = 1000000; bool notprime[MAXN+10]; int prime[MAXN+10], mu[MAXN+10], sum[MAXN+10]; long long GetAns(long long u){ long long ret1 = 0, ret2 = 0; for(int i=1;i<=u;i++){ int last = (u/(u/i)); ret1 += (sum[last] - sum[i-1]) * (u/i) * (u/i) * (u/i); ret2 += (sum[last] - sum[i-1]) * (u/i) * (u/i); i = last; } return ret1 + ret2*3 + 3; } void Init(long long Max){ mu[1] = 1; long long tmp; for(long long i=2;i<=Max;i++){ if(!notprime[i]){ mu[i] = -1; prime[++prime[0]] = i; } for(int j=1;j<=prime[0]&&(tmp=prime[j]*i)<=Max;j++){ notprime[tmp] = true; if(i%prime[j] == 0){ mu[tmp] = 0; break; } mu[tmp] = -mu[i]; } } for(int i=1;i<=Max;i++) sum[i] = sum[i-1] + mu[i]; } int main(){ int T; Init(1000000); cin>>T; while(T--){ long long n; cin>>n; cout<<GetAns(n)<<endl; } return 0; }
相关文章推荐
- OMAP3 DSS 初始化过程(1)总线关系
- Memcached分布式原理
- jQuery 插件编程精讲与技巧
- Leetcode 210. Course Schedule II
- linq jion多张表 group by
- windows::gvim配置pydiction详细过程
- Leetcode 207. Course Schedule
- nginx上设置禁止通过ip访问服务器,只能通过域名访问
- Matplotlib 如何显示中文
- Leetcode 124. Binary Tree Maximum Path Sum
- 【莫比乌斯反演】[BZOJ3529]数表
- 夺命雷公狗---微信开发05----根据用户输入返回指定图片,且图片入库
- PAT 1001 A+B 解题报告
- dojo的发展历史
- UIScrollView的相关内容
- 文章标题
- linux ipc之匿名管道
- 114. Flatten Binary Tree to Linked List
- 悟透JavaScript
- Android studio java.lang.UnsatisfiedLinkError