您的位置:首页 > 其它

POJ-3090 - Visible Lattice Points - 欧拉函数

2017-09-07 01:31 393 查看

链接:

  http://poj.org/problem?id=3090

题目:

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

题意:

  问你站在(0,0)点可以看到多少第一象限的点。

思路:

  这个图给的很直观,如果某个点到原点的斜率出现过的话,那么这个点就是被遮住看不见的。转化一下,如果这个点的横纵坐标互质,那么这个点就是可以被看见的。

  于是乎我先暴力了一发,果断T了,没想到t也比较大,以为O(n2)是可以过的。又琢磨了一下,原先写的循环的内层循环可以离线一下,想到了欧拉函数,改了一发果断过了。

实现:

#include <cstdio>
int n, ans, t, i, eular[1007], cas;
void Init () {
for (int i=0; i<1007; i++) eular[i] = i;
for (int i=2; i<1007; i++)
if (eular[i] == i) {
eular[i] = eular[i] / i * (i - 1);
for (int j=i+i; j<1007; j+=i) eular[j] = eular[j] / i * (i - 1);
}
}
int main() {
for(Init(), scanf("%d",&t), cas=1 ; cas<=t ; cas++) {
for(scanf("%d",&n), ans=i=1 ; i<=n ; i++) ans += eular[i]<<1;
printf("%d %d %d\n", cas, n, ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息