poj3090 欧拉函数与法雷级数
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 3889 | Accepted: 2144 |
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的图(有(n+1)^2个格点),求出图中可视点的个数,可视点就是在图中从(0,0)看不被遮挡的点,例如(1,1)是可视点,(2,2)不是,因为(2,2)被(1,1)给遮挡了
这一题和poj2478的解法类似,解答方法也相似,点此进入poj2478解题报告,这题是求法雷级数的题
然而也不能直接就把poj2478的代码个复制过来
因为对于这一题,并没有要求分子一定比分母小,也就是水(5,3)也是题目可视点,但进一步观察发现如果(a,b)是可视点,那么(b,a)也一定是可视点
则我们根据这个规律,我们就可以假设出a<b,则只要求出a<b的格点数,然后再乘以2
但还是会有问题,此题中(1,0),(0,1)也是格点数,但我们在运用欧拉函数时并不考虑0,并且也存在a=b的格点,即(1,1)
还好这样特殊的点并不多,只有三个,我们只需要特殊考虑就行了
刚开始是求欧拉函数没考虑边界大情形,RE了两次,最后发现问题,修正了一下,果然AC了
参考代码:
1 #include<iostream>
2 #include<cstdlib>
3 #include<cstdio>
4 #include<cstring>
5 #include<algorithm>
6 #include<cmath>
7 using namespace std;
8 int phi[1005];
9 int main()
10 {
11 int i , j ;
12 memset ( phi , 0 ,sizeof ( phi ) ) ;
13 phi[1]=1;
14 for ( i = 2 ; i <1005 ; i ++ )
15 {//筛选求phi
16 if ( ! phi [i] )
17 {
18 for ( j = i ; j <1005 ; j += i )
19 {
20 if ( ! phi [j] )
21 phi [j ] = j ;
22 phi [j] = phi [j] / i * ( i - 1 ) ;
23 }
24 }
25 }
26 int t ;
27 int k = 1 ;
28 cin >> t ;
29 while ( t-- )
30 {
31 int n ;
32 cin >> n ;
33 cout << k << ' ' << n << ' ';
34 int sum = 3 ;//特别考虑的三个点,(1,0)(0,1)(1,1)
35 for ( i = 2 ; i <= n ; i ++ )
36 sum += 2 *(phi [i] );
37 cout<<sum<<endl;
38 k++;
39 }
40 return 0;
41 }
作者:ACShiryu
出处:http://www.cnblogs.com/ACShiryu/
若非注明,本博客文章均为原创,版权归作者和博客园共有,欢迎转载,但必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。
该文章也同步发布在我的新浪微博中-ACShiryu's weibo,欢迎收听。