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

观察点在三维空间中的可见性问题
本文探讨了在三维空间中从某一点观察所有点的可见性问题,通过计算点的个数来解决这一问题。具体而言,文章利用最大公约数(gcd)的概念,区分了不同情况下的点数计算方法,包括没有零点的情况、存在一个零点的情况以及存在两个零点的情况。通过一系列数学推导和代码实现,展示了如何通过编程解决这一几何问题。

题目大意:

从坐标(0,0,0)处观察到所有在(n,n,n)范围内的点的个数,如果一条直线上出现多个点,除了第一个,后面的都视为被遮挡了

 

这题目稍微推导一下可得知 gcd(x,y,z) = 1的点是可观察到的,若三者的gcd>1,则这个点之前必然出现了一个(x/gcd(x,y,z) , y/gcd(x,y,z) , z/gcd(x,y,z))的点

那么因为 0 是无法计算gcd的 , 所以先不考虑0

1. x>0 , y>0 , z>0  ans = ∑x<=n∑y<=n∑z<=n[gcd(x,y,z)=1]  -> ∑x<=n∑y<=n∑z<=n∑d|gcd(x,y,z) mu[d]

2. 只存在一个0 ans = 3*(∑x<=n∑y<=n[gcd(x,y)=1]) -> 3*(∑x<=n∑y<=n∑d|gcd(x,y) mu[d])

3.3个数两个为0 ans = 3

那么只要将上面的3个值相加就是我们要求的答案了

 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4 const int MAXN = 1000000;
 5 #define ll long long
 6 int mu[MAXN+5] , prime[MAXN/10];
 7 bool check[MAXN+5];
 8 
 9 void getMu(int n)
10 {
11     memset(check , 0 ,  sizeof(check));
12     int tot=0;
13     check[1] = true , mu[1]=1 , mu[2]=-1;
14     for(int i=2 ; i<=n ; i++){
15         if(!check[i]) prime[tot++]=i , mu[i]=-1;
16         check[i] = true;
17         for(int j=0 ; j<tot ; j++){
18             if(i*prime[j]>n) break;
19             check[i*prime[j]]=true;
20             if(i%prime[j] == 0){
21                 mu[i*prime[j]] = 0;
22                 break;
23             }else{
24                 mu[i*prime[j]] = -mu[i];
25             }
26         }
27     }
28 }
29 
30 int main()
31 {
32    // freopen("a.in" , "r" , stdin);
33     getMu(MAXN);
34     int T , n;
35     scanf("%d" , &T);
36     while(T--)
37     {
38         scanf("%d" , &n);
39         ll ans = 0;
40         for(int i=1 ; i<=n  ; i++){
41             ll tmp1 = (ll)(n/i)*(n/i)*(n/i)*mu[i]; //坐标中一个零都不存在的情况
42             ll tmp2 = (ll)3*(n/i)*(n/i)*mu[i];  //坐标中有一个零的情况
43             ll tmp3 = (ll)3*(n/i)*mu[i]; //坐标中有两个零的情况
44             ans += tmp1+tmp2+tmp3;
45         }
46         printf("%lld\n" , ans);
47     }
48     return 0;
49 }

 

转载于:https://www.cnblogs.com/CSU3901130321/p/4424655.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值