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 : 




 
Sample Output : 

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 }

 

posted @ 2019-08-11 17:17  Spring-Onion  阅读(200)  评论(0编辑  收藏  举报