您的位置:首页 > 其它

SPOJ VLATTICE - Visible Lattice Points 莫比乌斯反演

2017-08-04 20:57 393 查看
做此提前可以先做二维的:点击打开链接

题目链接:点击打开链接

题目大意:

•有一个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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: