可见的点
在一个平面直角坐标系的第一象限内,如果一个点(x,y)与原点(0,0)的连线中没有通过其他任何点,则称该点在原点处是可见的。
例如,点(4,2)就是不可见的,因为它与原点的连线会通过点(2,1)。
部分可见点与原点的连线如下图所示:
编写一个程序,计算给定整数N的情况下,满足0≤x,y≤N的可见点(x,y)的数量(可见点不包括原点)。
输入格式
第一行包含整数C,表示共有C组测试数据。
每组测试数据占一行,包含一个整数N。
输出格式
每组测试数据的输出占据一行。
应包括:测试数据的编号(从1开始),该组测试数据对应的N以及可见点的数量。
同行数据之间用空格隔开。
数据范围
1≤N,C≤1000
输入样例:
4
2
4
5
231
输出样例:
1 2 5
2 4 13
3 5 21
4 231 32549
题解:
答案和欧拉函数有关,证明如下:
我们假设光的方程式
y
=
k
x
y=kx
y=kx所以一条直线上如果第一个点被挡住了那么后面的点都是不可见的。假设第一个点的坐标是
(
x
0
,
y
0
)
(x_0,y_0)
(x0,y0)直线方程转换成
y
=
(
y
0
/
x
0
)
∗
x
y=(y_0/x_0)*x
y=(y0/x0)∗x
1,当
x
0
和
y
0
不
互
质
的
时
候
x_0和y_0不互质的时候
x0和y0不互质的时候
d
=
g
c
d
(
x
0
,
y
0
)
d=gcd(x_0,y_0)
d=gcd(x0,y0)
那么存在最简分数(斜率)
y
1
/
x
1
y_1/x_1
y1/x1代表的
(
x
1
,
y
1
)
(x_1,y_1)
(x1,y1)在最左下角的点上面。他一定这条直线上是挡住光的第一个点。
2,当
x
0
和
y
0
互
质
的
时
候
x_0和y_0互质的时候
x0和y0互质的时候 。利用反证法,存在
x
1
,
y
1
x_1,y_1
x1,y1是这条直线的第一个点,因为斜率相等的原因,
x
1
=
x
0
/
d
,
y
1
=
y
0
/
d
x_1=x_0/d,y_1=y_0/d
x1=x0/d,y1=y0/d但是
x
0
,
y
0
x_0,y_0
x0,y0互质,所以d=1,这个点就是
x
0
,
y
0
x_0,y_0
x0,y0和假设矛盾所以不存在更左下角的点挡住光源。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int N = 1005;
int prime[N],st[N],phi[N],cnt,idx;
void init()
{
phi[1]=1;
for(int i=2;i<=N;i++){
if(!st[i]){
prime[cnt++]=i;
phi[i]=i-1;
}
for(int j=0;prime[j]*i<=N;j++){
st[prime[j]*i]=1;
if(i%prime[j]==0){
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
}
int main()
{
init();
int n, m;
cin >> m;
for (int T = 1; T <= m; T ++ ){
cin >> n;
int res = 1;
for (int i = 1; i <= n; i ++ ) res += phi[i] * 2;
cout << T << ' ' << n << ' ' << res << endl;
}
return 0;
}