题目传送门:POJ——3090 Visible Lattice Points
Time Limit: 1000MS | Memory Limit: 65536K |
---|---|
Total Submissions: 10420 | Accepted: 6304 |
Description
A lattice point (x, y) in the first quadrant (x and y are integers greater than or equal to 0), other than the origin, is visible from the origin if the line from (0, 0) to (x, y) does not pass through any other lattice point. For example, the point (4, 2) is not visible since the line from the origin passes through (2, 1). The figure below shows the points (x, y) with 0 ≤ x, y ≤ 5 with lines from the origin to the visible points.
Write a program which, given a value for the size, N, computes the number of visible points (x, y) with 0 ≤ x, y ≤ N.
Input
The first line of input contains a single integer C (1 ≤ C ≤ 1000) which is the number of datasets that follow.
Each dataset consists of a single line of input containing a single integer N (1 ≤ N ≤ 1000), which is the size.
Output
For each dataset, there is to be one line of output consisting of: the dataset number starting at 1, a single space, the size, a single space and the number of visible points for that size.
Sample Input
4
2
4
5
231
Sample Output
1 2 5
2 4 13
3 5 21
4 231 32549
题意:给你一个
(
n
+
1
)
∗
(
n
+
1
)
(n+1)*(n+1)
(n+1)∗(n+1)的矩阵,行列的编号都是从0到n,然后让你从(0,0)这个点往前看,能看见多少个点((0,0)这个点不算)。
思路:
我们可以发现,无论你怎么看,你都必定能看见(1,0),(0,1),(1,1),这三个点。然后其余的点,假设
(
x
,
y
)
(x,y)
(x,y)可以看的见,那么
g
c
d
(
x
,
y
)
gcd(x,y)
gcd(x,y)必定为1,可以这样想想,如果
g
c
d
(
x
,
y
)
=
=
k
,
(
k
!
=
1
)
gcd(x,y)==k ,(k!=1)
gcd(x,y)==k,(k!=1),那么当年看到
(
x
/
k
,
y
/
k
)
(x/k,y/k)
(x/k,y/k)这个点的时候,就已经挡住了后面的
(
x
,
y
)
(x,y)
(x,y)点,那么我们只需要找到每个数与其互为质数的个数就行了。而欧拉函数
φ
(
x
)
\varphi(x)
φ(x)就是表示了到x为止与x互质数的数量。那么这道题的答案就是:
a
n
s
=
3
+
2
∗
∑
i
=
2
n
φ
(
x
)
ans=3+2* \sum_{i=2}^n{\varphi(x)}
ans=3+2∗i=2∑nφ(x)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define LL long long
int f[1005];
void es()
{
for(int i=2;i<=1000;i++)
{
f[i]=i;
}
for(int i=2;i<=1000;i++)
{
if(f[i]==i)
{
for(int j=i;j<=1000;j+=i)
{
f[j]=f[j]/i*(i-1);
}
}
}
}
int main()
{
f[1]=1;
es();
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
int n;
scanf("%d",&n);
int ans=0;
for(int i=2;i<=n;i++)
{
ans+=f[i];
}
printf("%d %d %d\n",i,n,ans*2+3);
}
return 0;
}