测试地址:Visible Lattice Points
题目大意:在三维空间中,我们说一个点是可见的当且仅当它与点
做法:这一道题是POJ3090的加强版,从二维扩展到了三维,我写的POJ3090题解在此。而这题就不能简单地使用欧拉函数的性质来解决问题了,而需要用莫比乌斯反演来解决。
将点分为三种情况:1.
显然暴力求这个式子会炸,这时候我们就要用到一个莫比乌斯函数的性质:
分析第四个求和号下面的条件,显然
这个式子等价于:
那么这个式子显然等于:
这就是第一种情况的答案了。第二种情况就是要分别求
以下是本人代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
using namespace std;
int T;
ll N,mu[1000010],sum[1000010];
bool prime[1000010]={0};
void calc_mu()
{
N=1000000;
for(int i=1;i<=N;i++) mu[i]=1;
for(int i=2;i<=N;i++)
if (!prime[i])
{
for(int j=1;i*j<=N;j++)
{
mu[i*j]*=-1;
if (j>1) prime[i*j]=1;
if (!(j%i)) {mu[i*j]=0;continue;}
}
}
sum[0]=0;
for(int i=1;i<=N;i++) sum[i]=sum[i-1]+mu[i];
}
int main()
{
scanf("%d",&T);
calc_mu();
while(T--)
{
scanf("%lld",&N);
ll ans=3,last;
for(ll d=1;d<=N;d=last+1)
{
last=N/(N/d);
ans+=((N/d)+3)*(N/d)*(N/d)*(sum[last]-sum[d-1]);
}
printf("%lld
",ans);
}
return 0;
}