POJ 3090 Visible Lattice Points (欧拉函数)

来源:互联网 发布:钱刷宝提示网络异常 编辑:程序博客网 时间:2024/06/13 13:50
Visible Lattice Points
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 6611 Accepted: 3946

Description

A lattice point (x, y) in the first quadrant (x andy 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, yN.

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

4245231

Sample Output

1 2 52 4 133 5 214 231 32549

Source

Greater New York 2006

大体题意:
告诉你坐标系的尺寸n*n,求出从(0,0)向第一象限看,能看到多少个点!
思路:
找规律题目,首先如果尺寸是1*1的话,你能看到3个点,
然后扩大尺寸,2*2的话,只是多了(2,1)和(1,2)因为这两个是对称的,所以我们可以只找一边,最后乘以2即可!
如果是3*3的话,增加了(3,1)(3,2)多了两个!
。。。。。
找多了会发现,多出来的点只是 与n 互质的数。
显然这个问题转化成了  求i(2<= i <= n)互质的数的数目 乘以2 ,在加上1这个特殊的点,
显然是欧拉函数问题,
直接枚举n ,用欧拉函数记录下增量递推一下即可!
详细见代码:
#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<cstdlib>#include<vector>#include<set>#include<map>#include<stack>#include<cctype>#include<string>#include<iostream>#include<queue>#define fout freopen("out.txt","w","stdout");#define mr make_pair#define fi first#define se secondusing namespace std;typedef long long ll;typedef unsigned long long LLU;const int maxn = 1000 + 5;const int mod = 1000000000;const double eps = 1e-8;const int inf = 0x3f3f3f3f;int gcd(int a,int b){    return !b?a:gcd(b,a%b);}int vis[maxn];vector<int>prime;int len_prime;int dp[maxn];void init(){    int m = sqrt(maxn) + 1;    for (int i = 2; i <= m; ++i) if (!vis[i])        for (int j = i*i; j < maxn; j += i)vis[j] = 1;    for (int i = 2; i < maxn; ++i)if (!vis[i])prime.push_back(i);    len_prime = (int)prime.size();    dp[1] = 3;    for (int nn = 2; nn < maxn; ++nn){        int n = nn;        int phi = n;        for (int i = 0; i < len_prime; ++i){            int pri = prime[i];            if (n % pri == 0){                phi = phi/pri*(pri-1);                while(n % pri == 0)n/=pri;            }        }        dp[nn] = dp[nn-1] + phi*2;    }}int main(){    int T,kase = 0;    init();    scanf("%d",&T);    while(T--){        int n;        scanf("%d",&n);        printf("%d %d %d\n",++kase,n,dp[n]);    }    return 0;}


0 0