Visible Lattice Points

题意

在第一象限,每个点和原点有连线,给N*N大小,求解线的数量

在这里插入图片描述![在这里插入图片描述](https://img-blog.csdnimg.cn/65377c6c1b9f4c829130a0f22a6f07d3.png)

解析

g c d ( x , y ) = m gcd(x,y)=m gcd(x,y)=m 可以分解为 m ∗ g c d ( x , y ) = 1 m*gcd(x,y)=1 mgcd(x,y)=1; 因此斜率肯定相同,会重复。所以只要统计 g c d ( x , y ) = 1 gcd(x,y)=1 gcd(x,y)=1 的个数。
现在的问题转化成, 0 < = x < = N , 0 < = y < = N 0<=x<=N , 0<=y<=N 0<=x<=N,0<=y<=N 求解 g c d ( x , y ) = 1 gcd(x,y)=1 gcd(x,y)=1 的个数。
我们枚举x从1~N,求解 ( 1 < = y < = x ) g c d ( x , y ) = 1 (1<=y<=x) gcd(x,y)=1 1<=y<=xgcd(xy)=1的个数,根据欧拉函数其值为 ϕ ( x ) \phi(x) ϕ(x),我们要考虑一下中间的对角线,因此最终答案为 ∑ x = 1 N ϕ ( x ) + 1 \sum_{x=1}^{N}\phi(x)+1 x=1Nϕ(x)+1
所以考虑筛法,在筛选的过程之中计算之和,预处理,最后通过O(1)输出。

代码

#include <iostream>
const int N=1005;
typedef long long ll;
using namespace std;
int phi[N]={0,1};
ll sum[N]={0,1};
int p[N],cnt;
int main()
{  
    int n;
    cin>>n;
    for(int i=2;i<=N;i++){
        if(phi[i]==0)p[++cnt]=i,phi[i]=i-1;
        for(int j=1;1ll*p[j]*i<=N;j++){
            if(i%p[j]==0){
                phi[i*p[j]]=phi[i]*p[j];
                break;
            }
            phi[i*p[j]]=phi[i]*phi[p[j]];
        }
        sum[i]=sum[i-1]+phi[i];
    }
    for(int i=1;i<=n;i++){
        int s;
        cin>>s;
        cout<<i<<" "<<s<<" "<<sum[s]*2+1<<endl;
    } 
}  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值