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

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

题意:

给 定 一 个 n × n × n 的 立 方 体 , 从 ( 0 , 0 , 0 ) 看 过 去 , 问 能 够 看 到 多 少 个 点 。 给定一个n×n×n的立方体,从(0,0,0)看过去,问能够看到多少个点。 n×n×n(0,0,0)

空 间 中 , 一 个 点 X 能 够 被 点 Y 看 到 的 充 要 条 件 是 : 点 X 和 点 Y 的 这 条 线 段 上 , 不 存 在 其 他 点 。 空间中,一个点X能够被点Y看到的充要条件是:点X和点Y的这条线段上,不存在其他点。 XYXY线

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


分析:

我 们 知 道 , 在 二 维 坐 标 系 中 , 点 ( x 1 , y 1 ) 和 点 ( x 2 , y 2 ) 之 间 不 存 在 其 他 点 的 充 要 条 件 是 : 我们知道,在二维坐标系中,点(x_1,y_1)和点(x_2,y_2)之间不存在其他点的充要条件是: (x1,y1)(x2,y2):

g c d ( x 2 − x 1 , y 2 − y 1 ) = 1 gcd(x_2-x_1,y_2-y_1)=1 gcd(x2x1,y2y1)=1

在 三 维 坐 标 系 中 , 点 ( x 1 , y 1 , z 1 ) 和 点 ( x 2 , y 2 , z 2 ) 之 间 不 存 在 其 他 点 的 充 要 条 件 是 : 在三维坐标系中,点(x_1,y_1,z_1)和点(x_2,y_2,z_2)之间不存在其他点的充要条件是: (x1,y1,z1)(x2,y2,z2):

g c d ( x 2 − x 1 , y 2 − y 1 , z 2 − z 1 ) = 1 gcd(x_2-x_1,y_2-y_1,z_2-z_1)=1 gcd(x2x1,y2y1,z2z1)=1

由 于 我 们 从 ( 0 , 0 , 0 ) 看 , 所 以 条 件 为 : g c d ( x 2 − 0 , y 2 − 0 , z 2 − 0 ) = 1 由于我们从(0,0,0)看,所以条件为:gcd(x_2-0,y_2-0,z_2-0)=1 (0,0,0)gcd(x20,y20,z20)=1

由 于 三 维 坐 标 ( i , j , k ) 都 是 可 能 为 0 的 , 因 此 我 们 先 考 虑 特 殊 情 况 : 由于三维坐标(i,j,k)都是可能为0的,因此我们先考虑特殊情况: (i,j,k)0

① 、 当 其 中 有 两 维 坐 标 为 0 时 , 我 们 能 够 看 到 3 个 点 : ( 1 , 0 , 0 ) 、 ( 0 , 1 , 0 ) 、 ( 0 , 0 , 1 ) ①、当其中有两维坐标为0时,我们能够看到3个点:(1,0,0)、(0,1,0)、(0,0,1) 03(1,0,0)(0,1,0)(0,0,1)

② 、 当 其 中 有 一 维 坐 标 为 0 时 , 能 够 看 到 的 点 的 数 量 是 : 3 × ∑ i = 1 n ∑ j = 1 n [ g c d ( i , j ) = = 1 ] ②、当其中有一维坐标为0时,能够看到的点的数量是:3×\sum_{i=1}^n\sum_{j=1}^n[gcd(i,j)==1] 03×i=1nj=1n[gcd(i,j)==1]

③ 、 当 所 有 坐 标 都 不 为 0 时 , 能 够 看 到 的 点 点 数 量 是 : ∑ i = 1 n ∑ j = 1 n ∑ k = 1 n [ g c d ( i , j , k ) = = 1 ] ③、当所有坐标都不为0时,能够看到的点点数量是:\sum_{i=1}^n\sum_{j=1}^n\sum_{k=1}^n[gcd(i,j,k)==1] 0i=1nj=1nk=1n[gcd(i,j,k)==1]

则 答 案 为 : 则答案为:

A n s = 3 + 3 × ∑ i = 1 n ∑ j = 1 n [ g c d ( i , j ) = = 1 ] + ∑ i = 1 n ∑ j = 1 n ∑ k = 1 n [ g c d ( i , j , k ) = = 1 ] Ans=3+3×\sum_{i=1}^n\sum_{j=1}^n[gcd(i,j)==1]+\sum_{i=1}^n\sum_{j=1}^n\sum_{k=1}^n[gcd(i,j,k)==1] Ans=3+3×i=1nj=1n[gcd(i,j)==1]+i=1nj=1nk=1n[gcd(i,j,k)==1]

根 据 反 演 定 理 , 我 们 很 快 得 到 : 根据反演定理,我们很快得到:

∑ i = 1 n ∑ j = 1 n [ g c d ( i , j ) = = 1 ] = ∑ i = 1 n μ ( i ) ⌊ n i ⌋ ⌊ n i ⌋ \sum_{i=1}^n\sum_{j=1}^n[gcd(i,j)==1]=\sum_{i=1}^n\mu(i)\lfloor\frac{n}{i}\rfloor\lfloor\frac{n}{i}\rfloor i=1nj=1n[gcd(i,j)==1]=i=1nμ(i)inin

同 理 : 同理: :

∑ i = 1 n ∑ j = 1 n ∑ k = 1 n [ g c d ( i , j , k ) = = 1 ] = ∑ i = 1 n μ ( i ) ⌊ n i ⌋ ⌊ n i ⌋ ⌊ n i ⌋ \sum_{i=1}^n\sum_{j=1}^n\sum_{k=1}^n[gcd(i,j,k)==1]=\sum_{i=1}^n\mu(i)\lfloor\frac{n}{i}\rfloor\lfloor\frac{n}{i}\rfloor\lfloor\frac{n}{i}\rfloor i=1nj=1nk=1n[gcd(i,j,k)==1]=i=1nμ(i)ininin

综 上 答 案 为 : 综上答案为:

A n s = 3 + ∑ i = 1 n μ ( i ) ⌊ n i ⌋ ⌊ n i ⌋ ( ⌊ n i ⌋ + 3 ) Ans=3+\sum_{i=1}^n\mu(i)\lfloor\frac{n}{i}\rfloor\lfloor\frac{n}{i}\rfloor(\lfloor\frac{n}{i}\rfloor+3) Ans=3+i=1nμ(i)inin(in+3)

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>

#define ll long long

using namespace std;

const int N = 1000010;

int T, n;
int mu[N], primes[N], cnt, sum[N];
bool st[N];
ll f[N];

void get_prime(int n)
{
    mu[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(!st[i])
        {
            primes[cnt++]=i;
            mu[i]=-1;
        }
        for(int j=0;primes[j]*i<=n;j++)
        {
            st[primes[j]*i]=true;
            if(i%primes[j]==0)
            {
                mu[i*primes[j]]=0;
                break;
            }
            mu[i*primes[j]]=mu[i]*-1;
        }
    }
    for(int i=1;i<=n;i++) sum[i]=sum[i-1]+mu[i];
}

ll cal(int n)   
{
    ll res=0;
    for(int i=1, r=1;i<=n;i=r+1)
    {
        r=n/(n/i);
        r=min(r,n);
        res+=(ll)(sum[r]-sum[i-1])*(n/i)*(n/i)*(n/i+3);
    }
    return res;
}

int main()
{
    get_prime(N-1);
    memset(f,-1,sizeof f);
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        printf("%lld\n",cal(n)+3);
    }
    
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值