SPOJ7001(SummerTrainingDay04-N 莫比乌斯反演)
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
1 //2017-08-04 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 7 using namespace std; 8 9 const int N = 1000010; 10 int mu[N], prime[N], tot, phi[N]; 11 long long plane[N]; 12 bool book[N]; 13 14 void Moblus()//求出莫比乌斯函数 15 { 16 memset(book,false,sizeof(book)); 17 mu[1] = 1; 18 int tot = 0; 19 for(int i = 2; i <= N; i++){ 20 if(!book[i]){ 21 prime[tot++] = i; 22 mu[i] = -1; 23 } 24 for(int j = 0; j < tot; j++){ 25 if(i * prime[j] > N) break; 26 book[i * prime[j]] = true; 27 if( i % prime[j] == 0){ 28 mu[i * prime[j]] = 0; 29 break; 30 }else{ 31 mu[i * prime[j]] = -mu[i]; 32 } 33 } 34 } 35 } 36 37 void getphi() 38 { 39 int i,j; 40 phi[1]=1; 41 for(i=2;i<=N;i++)//相当于分解质因式的逆过程 42 { 43 if(!book[i]) 44 { 45 prime[++tot]=i;//筛素数的时候首先会判断i是否是素数。 46 phi[i]=i-1;//当 i 是素数时 phi[i]=i-1 47 } 48 for(j=1;j<=tot;j++) 49 { 50 if(i*prime[j]>N) break; 51 book[i*prime[j]]=1;//确定i*prime[j]不是素数 52 if(i%prime[j]==0)//接着我们会看prime[j]是否是i的约数 53 { 54 phi[i*prime[j]]=phi[i]*prime[j];break; 55 } 56 else phi[i*prime[j]]=phi[i]*(prime[j]-1);//其实这里prime[j]-1就是phi[prime[j]],利用了欧拉函数的积性 57 } 58 } 59 } 60 61 int main() 62 { 63 int T, n; 64 scanf("%d", &T); 65 Moblus(); 66 getphi(); 67 plane[2] = 1; 68 for(int i = 3; i < N; i++){ 69 plane[i] = plane[i-1]+phi[i]; 70 } 71 while(T--){ 72 scanf("%d", &n); 73 long long ans = 3; 74 for(int d = 1; d <= n; d++){ 75 int tmp = (int)(n/d); 76 ans += (long long)mu[d]*tmp*tmp*tmp; 77 } 78 ans += 3*(plane[n]*2+1); 79 printf("%lld\n", ans); 80 } 81 82 return 0; 83 }