Visible Lattice Points SPOJ - VLATTICE (莫比烏斯反演)
阿新 • • 發佈:2018-11-15
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
對題意進行簡單的轉化就會發現題目求的是
(在三個座標面上,和在空間中)
令
再有
據莫比烏斯反演
∴
同理
將兩個式子合併得到最終得到
由於還需要加上三條座標軸,所以:
AC程式碼:
#include<cstdio> #include<iostream> #include<cstring> using namespace std; const long long MAXN=1e6+5; //線性篩法求莫比烏斯函式 bool check[MAXN+10]; long long prime[MAXN+10]; int mu[MAXN+10]; void Moblus() { memset(check,false,sizeof(check)); mu[1] = 1; long long tot = 0; for(long long i = 2; i <= MAXN; i++) { if( !check[i] ){ prime[tot++] = i; mu[i] = -1; } for(long long j = 0; j < tot; j++) { if(i * prime[j] > MAXN) break; check[i * prime[j]] = true; if( i % prime[j] == 0){ mu[i * prime[j]] = 0; break; }else{ mu[i * prime[j]] = -mu[i]; } } } } int main() { Moblus(); int t; scanf("%d",&t); while(t--) { long long n; scanf("%lld",&n); long long ans=3; for(long long i=1;i<=n;i++) ans+=mu[i]*(n/i)*(n/i)*(n/i+3); printf("%lld\n",ans); } }