您的位置:首页 > 其它

【SPOJ VLATTICE】Visible Lattice Points——莫比乌斯反演3

2016-05-12 14:07 435 查看
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

题意:给你一个三维的地图,坐标为(0,0,0)∼(n,n,n)(0,0,0)\sim (n,n,n),判断有多少个坐标与原点之间的连线不经过其他的点。

思路:不经过其他的点也就是gcd(x,y,z) = 1,所以题意就变成在[1,n][1,n]中有多少三元组(x,y,z)的gcd 等于1.

令g(n)表示n|gcd(x,y,z)的个数

f(n)表示gcd(x,y,z)等于n的个数,所以g(n)=∑n|df(d)g(n) = \sum\limits_{n|d} f(d),所以f(n)=∑n|dμ(dn)g(d)f(n) = \sum\limits_{n|d}\mu(\frac{d}{n})g(d)

由于n=1n = 1所以ans=f(1)=∑d=1nμ(d)g(d)=∑d=1nμ(d)⌊nd⌋⌊nd⌋⌊nd⌋ans = f(1) = \sum\limits_{d=1}^n \mu(d)g(d) =\sum\limits_{d=1}^n\mu(d)\lfloor \frac{n}{d}\rfloor\lfloor \frac{n}{d}\rfloor\lfloor \frac{n}{d}\rfloor 。

在计算的时候由于(0,0,1),(0,1,0),(1,0,0)(0,0,1),(0,1,0),(1,0,0)不会被计算到所以初始答案为3,而在计算的过程中xoy,xoz,yozxoy,xoz,yoz的面不会计算到,所以在计算的时候也要加上。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

typedef long long LL;

const int Max = 1000100;

bool vis[Max];

int prime[Max],cnt;

int mu[Max];

void GetMobius() {

memset(vis,false,sizeof(vis));

mu[1] = 1; cnt = 0;

for(int i = 2 ;i < Max; i++){

if(!vis[i]) {

prime[cnt++] = i;

mu[i] = -1;
}

for(int j = 0; j < cnt && i*prime[j] < Max ; j++) {

vis[i*prime[j]] = true;

if(i % prime[j]) mu[i*prime[j]] = -mu[i];

else {

mu[i*prime[j]] = 0;

break;
}
}

}
}

LL Cal(LL n){

int end;

LL ans =3;

for(int i = 1;i <= n; i ++){

ans+=mu[i]*(n/i)*(n/i)*(n/i+3);
}

return ans;
}

int main() {

int T,n;

GetMobius();

scanf("%d",&T);

while(T--) {

scanf("%d",&n);

LL ans = Cal(n);

printf("%lld\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: