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
这题是 bzoj2005 的升级版,从二维变成了三维,而且还有不同的是这题需要计算坐标轴上的点。
我们用莫比乌斯反演分别求出三个点都不是零的答案,有一个点是零的答案,还有就是在坐标轴上的点,有两个点是零的答案,加起来就是要求的点数了。
我们同样是设F(n) 为gcd是n的倍数的个数,f(n)为gcd是n的个数,
用莫比乌斯反演求出 f(1)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
const int maxn = 1e6 + 10;
int p[maxn/10];
int flag[maxn];
int mu[maxn];
int cnt = 0;
void init()
{
int i,j;
mu[1] = 1;
for(i=2;i<maxn;i++)
{
if(!flag[i])
{
p[cnt++] = i;
mu[i] = -1;
}
for(j=0;j<cnt&&p[j]*i<maxn;j++)
{
flag[p[j]*i] = 1;
if(i % p[j] == 0)
{
mu[p[j]*i] = 0;
break;
}
mu[p[j]*i] = -mu[i];
}
}
}
int main(void)
{
int T,n,i,j;
init();
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
LL sum1 = 0;
LL sum2= 0;
for(i=1;i<=n;i++)
{
sum1 += (LL)mu[i]*(n/i)*(n/i)*(n/i);
sum2 += (LL)mu[i]*(n/i)*(n/i);
}
LL ans = sum1 + sum2*3 + 3;
printf("%lld\n",ans);
}
return 0;
}