Visible Lattice Points(原点连线不经过其他点

# 题意

在一个平面坐标系中,如果一个点和原点(0,0)的连线不经过任何一个点,那么这个点就是可见的

例如(4,2)点和(0,0)的连线会经过(2,1)点所以是不可见的

t组数据每组给定一个n求出

0 ≤ x,y ≤ n中所有的可见点

数据范围:

1 ≤ t,n ≤ 1000

# 题解

y=kx 第一个经过的点是可见的 , 第一个点y=k * x 的第一个点(x,y)即x和y互质,

如果不互质即gcd(x,y)=d ,x/d,y/d 显然也在直线上

除去(1,0)、(0,1)、(1,1)三个点以外,一个点(x,y)和原点的连写不会经过任何一个点即gcd(x,y)=1

即互质,所以对大于1的x和y求出互质点的数量加上三个点即可

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N=1010;
 4 int primes[N],cnt;
 5 bool st[N];
 6 int phi[N];
 7 int n;
 8 void get_primes(int n){
 9     phi[1]=1;
10     for(int i=2;i<=n;i++){
11         if(!st[i]){
12             primes[cnt++]=i;
13             phi[i]=i-1;
14         }
15         for(int j=0;primes[j] <= n/i;j++){
16             st[primes[j]*i]=true;
17             if(i%primes[j]==0){
18                 phi[i*primes[j]]=primes[j]*phi[i];
19                 break;
20             }
21             phi[i*primes[j]]=phi[i]*(primes[j]-1);
22         }
23     }
24 }
25 void work(int t){
26     cin>>n;
27     int ans=0;
28     for(int i=2;i<=n;i++)
29         ans+=phi[i];
30     ans*=2;
31     ans+=3;
32     cout<<t<<' ';
33     cout<<n<<' ';
34     cout<<ans<<endl;
35 }
36 int main(){
37     get_primes(N);
38     int t;
39     cin>>t;
40     for(int i=1;i<=t;i++){
41         work(i);
42     }
43     return 0;
44 }

 

posted @ 2020-04-05 14:07  Hyx'  阅读(277)  评论(0编辑  收藏  举报