UVA10214 Trees in a Wood. 欧拉phi函数

只看某一个象限 能看到的数 == 一个 象限*4+4

能看到的树既距离原点的距离 gcd(x,y)==1

a 和 b 一大一小 预处理2000以内的phi函数,枚举小的一条边

从1...a 与 a gcd 为 1 的数的个数就是 phi(a)

从 1+a ... 2*a  与 a gcd 为 1 的数的个数 因为 GCD(i,a) = GCD(i+a,a) 所以还是 phi(a)

....

Trees in a Wood.

Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu

Submit Status

Description

Problem H

Trees in a Wood.

Input: Standard Input

Output: Standard Output

Time Limit: 10 seconds

Background

The saying ``You can‘t see the wood for the trees‘‘ is not only a cliche, but is also incorrect. The real problem is that you can‘t see the trees for the wood. If you stand in the middle of a wood, the trees tend to obscure each other and the
number of distinct trees you can actually see is quite small. This is especially true if the trees are planted in rows and columns, because they tend to line up. The purpose of this problem is to find how many distinct trees one can see if one were standing
on the position of a tree in the middle of the wood.

The Problem

For a mathematically more precise description we assume that you are situated at the origin of a coordinate system in the plane.

Trees are planted at all positions , with |x|<=a and |y|<=b .

A tree at position (x,y) can be seen from the origin if there are no other trees on the straight line from (0,0) to (x,y) . Find the number K of all the trees in the wood that can be seen from the origin and the number N of all the trees to
compute the fraction .

Hint: The Euler phi function is defined to be the number of integers m in
the range 1≤m≤n relatively prime to n :

Instead of counting (an adequate method for small n !) you could as well use the following identity:

Hint: Remember that gcd (m,n)= gcd (m+n,n)= gcd (m+2n,n)= gcd (m+in,i)

You might be surprised that the fraction converges to 0.607927
for an infinitely large wood.

The Input

Each scenario consists of a line with the two numbers a and b (separated by a white space), with 1 <= a <= 2000 and 1 <= b <= 2000000 Input is terminated by a line with two zeros.

The Output

For each scenario print a line containing the fraction with a precision of 7 digits after the decimal point.
Error less than 2e-7 or 2*10^(-7) will be tolerated.

Sample Input

3 2

0 0

Sample Output

0.7058824


Collected from TUD Programming Contest

Source

Root :: AOAPC II: Beginning Algorithm Contests (Second Edition) (Rujia Liu) :: Chapter 10. Maths :: Examples

Submit Status

/* ***********************************************
Author        :CKboss
Created Time  :2015年02月03日 星期二 22时13分33秒
File Name     :UVA10214.cpp
************************************************ */

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>

using namespace std;

int gcd(int a,int b)
{
	return (b==0)?a:gcd(b,a%b);
}

int phi[2200];
int GCD[2020][2020];

void phi_table(int n)
{
	phi[1]=1;
	for(int i=2;i<=n;i++)
	{
		if(!phi[i])
		{
			for(int j=i;j<=n;j+=i)
			{
				if(!phi[j]) phi[j]=j;
				phi[j]=phi[j]*(i-1)/i;
			}
		}
	}
}

void init()
{
	phi_table(2010);
	for(int i=1;i<=2000;i++)
		for(int j=1;j<=2000;j++)
			if(GCD[i][j]==0)
				GCD[i][j]=GCD[j][i]=gcd(i,j);
}

int a,b;

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);

	init();
	while(scanf("%d%d",&a,&b)!=EOF)
	{
		if(a==0&&b==0) break;
		if(a>b) swap(a,b);
		double ret=0;
		for(int i=1;i<=a;i++)
		{
			int duan = b/i;
			int yu = b%i;
			ret += duan * phi[i];
			for(int j=1;j<=yu;j++)
			{
				if(GCD[j][i]==1)
					ret+=1;
			}
		}
		ret = ret*4 + 4;
		double all = (2.*a+1)*(2.*b+1)-1.;
		double ans = ret/all;
		printf("%.7lf\n",ans);
	}

    return 0;
}
时间: 2024-07-31 14:32:54

UVA10214 Trees in a Wood. 欧拉phi函数的相关文章

HDU 1286 找新朋友 (欧拉phi函数打表)

题意:你懂得. 析:一看这个题应该是欧拉phi函数,也就说欧拉phi函数是指求从 1 到 n 中与 n 互素的数的个数,这个题很明显是这个意思嘛,不多说了. 代码如下: #include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn = 32768 + 5; int phi[maxn+5]; void phi_table(int n){ memset

学习欧拉phi函数的思考

其正确性思考写在了代码片上 忘记一件事:欧拉phi函数的作用是用来求1~n中与n互素的数的个数 #include<cstdio> #include<cstring> #include<cmath> int phi[5000000]; ///考虑到若所计算的数字是6,当i=2和i=3时都将会进入内层循环, ///一旦进入内层循环就会在该素数的基础上进行欧拉公式的运算 ///插入:欧拉公式:phi(n)=n*(1-1/p1)*(1-1/p2)*...(1-1/pn) ///

UVA 11440 Help Mr. Tomisu 欧拉phi函数

欧拉phi函数的改进版..... Help Tomisu Time Limit: 7000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu Submit Status Description Problem D Help Mr. Tomisu Input: Standard Input Output: Standard Output After wasting a significant time of his life in probl

HDU ACM 1286-找新朋友-欧拉phi函数

φ函数的值,通式:φ(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)-..(1-1/pn),其中p1, p2--pn为x的所有质因数,x是不为0的整数.φ(1)=1(唯一和1互质的数(小于等于1)就是1本身). #include<iostream> #include<cmath> using namespace std; int Get(int n) { int res,i; if(n==0) return 0; else { res=n; for(i=2

UVa10214 - Trees in a Wood.(数论)

只看某一个象限 能看到的数 == 一个 象限*4+4 能看到的树既距离原点的距离 gcd(x,y)==1 a 和 b 一大一小 预处理2000以内的phi函数,枚举小的一条边 从1...a 与 a gcd 为 1 的数的个数就是 phi(a) 从 1+a ... 2*a 与 a gcd 为 1 的数的个数 因为 GCD(i,a) = GCD(i+a,a) 所以还是 phi(a) #include<iostream> #include<algorithm> #include<c

欧拉除了函数,还有个回路----图论之路之欧拉路径欧拉回路

首先我们来百度一下,欧拉路径以及回路的定义: 若图G中存在这样一条路径,使得它恰通过G中每条边一次,则称该路径为欧拉路径.若该路径是一个圈,则称为欧拉(Euler)回路. 具有欧拉回路的图称为欧拉图(简称E图).具有欧拉路径但不具有欧拉回路的图称为半欧拉图. 通俗来说,就是欧拉路径就是图中的每条边经过却只经过一次的路径,而最后回到起点的路径就是欧拉回路. 那给你一个图怎么判断存不存在,欧拉路径或者欧拉回路呢 首先,判断图是不是连通的,这个就很简单了,dfs或者并查集都可以. 然后就是根据定理 欧

[BZOJ 2190][SDOI2008]仪仗队(欧拉函数)

Description 作为体育委员,C君负责这次运动会仪仗队的训练.仪仗队是由学生组成的N * N的方阵,为了保证队伍在行进中整齐划一,C君会跟在仪仗队的左后方,根据其视线所及的学生人数来判断队伍是否整齐(如下图).现在,C君希望你告诉他队伍整齐时能看到的学生人数. Solution 能被看到的只能是坐标(x,y)x与y互质的学生 观察可以发现1到n-1欧拉phi函数的和*2+1即答案 #include<iostream> #include<cstdio> #include<

POJ 2478 Farey Sequence 筛选法求欧拉函数

题目来源:POJ 2478 Farey Sequence 题意:输入n 求 phi(2)+phi(3)+phi(4)+...+phi(n) 思路:用类似筛法的方式计算phi(1), phi(2), ..., phi(n) 再求前缀和 #include <cstdio> #include <cstring> #include <cmath> //欧拉phi函数 const int maxn = 1000010; typedef long long LL; int eule

模板——欧拉函数

//计算欧拉phi函数,phi(n)为不超过n且与n互素的整数个数 int euler_phi(int n) { int m = (int)sqrt(n+0.5); int ans = n; for(int i = 2; i <= m; i++) if(n % i == 0){ ans = ans / i * (i-1); while(n % i == 0) n /= i; } if(n > 1) ans = ans / n * (n-1); return ans; } //用类似筛法计算ph