您的位置:首页 > 其它

SPOJ VLATTICE Visible Lattice Points 初入莫比乌斯

2015-07-30 11:55 148 查看
题意:求两个点(x,y,z)的连线不经过其他点有几个

解:即为求GCD(x,y,z)为1的点有几个

解一:因为x,y,z均在1~n内,所以可以用欧拉函数解出

解二:莫比乌斯反演

设f
为GCD(x,y,z)=n的个数

设F[b]为b|GCD(x,y,z)的个数,很明显F[b]=(n/i)*(n/i)*(n/i)

所以F
=sigema(b|n,f[b]);

f
=sigema(n|b,mu
,F
)

#include <stdio.h>
#include <string.h>
const int maxn=1000005;
int prime[maxn];
int num[maxn];
int mu[maxn];
void mobius()
{
memset(num,0,sizeof(num));
mu[1]=1;
int all=0;
for(int i=2;i<maxn;i++)
{
if(!num[i])
{
prime[all++]=i;
mu[i]=-1;
}
for(int j=0;j<all&&i*prime[j]<maxn;j++)
{
num[i*prime[j]]=1;
if(i%prime[j])
mu[i*prime[j]]=-mu[i];
else
{
mu[i*prime[j]]=0;
break;
}
}
}
return ;
}
int main()
{
int t;
int n;
long long sum;
mobius();
while(scanf("%d",&t)!=-1)
{
while(t--)
{
sum=3;                       //x,y,z轴
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
sum+=(long long)mu[i]*(n/i)*(n/i)*((n/i)+3);            //在面上的点,所以+3
}
printf("%lld\n",sum);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: