做此提前可以先做二维的:点击打开链接
题目链接:点击打开链接
题目大意:
•
有一个
n*
n
*
n
的三维格点,问在原点
(0,0,0)
处能看到多少个格点?
(n<=1000000,50
组数据
)
思路:
莫比乌斯反演!
什么是莫比乌斯反演?
求莫比乌斯的函数;
int prime[maxn],mu[maxn];
bool unprime[maxn];
long long n;
void moblus()
{
int i,j,k = 0;
mu[1]=1;
for(i = 2; i <maxn; i++)
{
if(!unprime[i])
{
prime[k++] = i;
mu[i] =-1;//此处处理phi(p)
}
for(j = 0; j < k && prime[j]*i <maxn; j++)
{
unprime[prime[j] *i] = true;
if(i % prime[j] != 0)
{
//p不是i的约数
mu[prime[j]*i] = -mu[i];//欧拉数加一 所以莫比乌斯数乘以-1
}
else
{
//p是i的约数 说明有两个相同的质数
mu[prime[j]*i] =0;
break;
}
}
}
}
AC代码如下
#include <cstdio>
#include <cstring>
#include <algorithm>
#include<iostream>
#include<map>
using namespace std;
#define maxn 1000005
#define mod 9901
int prime[maxn],mu[maxn];
bool unprime[maxn];
long long n;
void moblus()
{
int i,j,k = 0;
mu[1]=1;
for(i = 2; i <maxn; i++)
{
if(!unprime[i])
{
prime[k++] = i;
mu[i] =-1;//此处处理phi(p)
}
for(j = 0; j < k && prime[j]*i <maxn; j++)
{
unprime[prime[j] *i] = true;
if(i % prime[j] != 0)
{
//p不是i的约数
mu[prime[j]*i] = -mu[i];//欧拉数加一 所以莫比乌斯数乘以-1
}
else
{
//p是i的约数 说明有两个相同的质数
mu[prime[j]*i] =0;
break;
}
}
}
}
int main()
{
int t;
scanf("%d",&t);
moblus();
for(int cas=1;cas<=t;cas++)
{
scanf("%lld",&n);
long long sum=3;
for(int i=1;i<=n;i++)
sum+=mu[i]*(n/i)*(n/i)*(n/i+3);
printf("%lld\n",sum);
}
return 0;
}