Visible Lattice Points(莫比乌斯反演)
题目:
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.
Input :
The first line contains the number of test cases T. The next T lines contain an interger N
Output :
Output T lines, one corresponding to each test case.
Sample Input :
3
1
2
5
Sample Output :
7
19
175
Constraints :
T <= 50
1 <= N <= 1000000
解题报告:
关于莫比乌斯反演求这个gcd的问题,重要的就是理解怎么来的,这就稍微有点难度了,代码不是很难实现,关于这道题目我参考的这位大佬的博客:https://blog.csdn.net/baiyifeifei/article/details/82954002,推导过程比较详细了,
我觉得就是要掌握一个全局和部分的关系,才可以实现的。
ac代码:
1 //from::Onion 2 //kuangbin Visible Lattice Points 莫比乌斯反演 3 #include<iostream> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdio> 7 #include<cmath> 8 using namespace std; 9 typedef long long ll; 10 11 const int maxn =1e6+1000; 12 int prime[maxn]; 13 int mu[maxn]; 14 bool vis[maxn]; 15 int cnt; 16 ll n; 17 18 void db_Onion() 19 { 20 cnt=0; 21 mu[1]=1; 22 vis[0]=vis[1]=1; 23 for(int i=2;i<maxn;i++) 24 { 25 if(!vis[i]) 26 { 27 prime[cnt++]=i; 28 mu[i]=-1; 29 } 30 for(int j=0;j<cnt&&prime[j]*i<maxn;j++) 31 { 32 vis[prime[j]*i]=1; 33 if(i%prime[j]==0) 34 { 35 mu[i*prime[j]]=0; 36 } 37 else 38 { 39 mu[i*prime[j]]=-mu[i]; 40 } 41 } 42 } 43 } 44 int main() 45 { 46 db_Onion(); 47 int t; 48 scanf("%d",&t); 49 while(t--) 50 { 51 scanf("%d",&n); 52 ll ans=0; 53 for(int i=1;i<=n;i++) 54 { 55 ll tmp=floor(n/i); 56 ans+=(mu[i]*tmp*tmp*tmp)+3*(mu[i]*tmp*tmp); 57 } 58 printf("%lld\n",ans+3); 59 } 60 }