Enumerating Rational Numbers UVA - 11327 欧拉函数

欧拉函数

题目链接:https://vjudge.net/problem/UVA-11327

题意:

for d = 1 to infinity do

  for n = 0 to d do

    if gcd(n,d) = 1 then print n/d

按分母从小到大顺序,输出第k个最简真分数(即分子分母互质 && 分子小于等于分母)

注意:特殊的,第一个为0/1,第二个为1/1;

数列为:0/1, 1/1, 1/2, 1/3, 2/3, 1/4, 3/4, 1/5, 2/5, 3/5, 4/5, 1/6, 5/6, 1/7, . . .

题解:

  打表欧拉函数,记录前缀和。利用分组查找,先通过二分查找得出第n个数属于哪个分母范围内的,再通过暴力枚举与该分母互质的合理分子。

特别要处理当分母为1时,分子可以为0,1

  

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 using namespace std;
 5 #define N 2000005 // 由样例可知最大数组范围为200000
 6 #define ll long long
 7 
 8 ll oula[N]; //记录欧拉函数 
 9 ll sum[N]; //记录前缀和
10 
11 int euler_phi(int n) { //计算欧拉函数
12     int ans = n;
13     for (int i = 2; i * i <= n; i++) {
14         if (n % i == 0) {
15             ans = ans / i * (i - 1);
16             while (n % i == 0)
17                 n /= i;
18         }
19     }
20     if (n > 1)
21         ans = ans / n * (n - 1);
22     return ans;
23 }
24 
25 void init() { //计算前缀和
26     sum[0] = oula[0] = 0;
27     oula[1] = 2;sum[1] = 2;//特别处理分母为1的情况
28     for (int i = 2; i < N; i++) {
29         oula[i] = euler_phi(i);
30         sum[i] = sum[i - 1] + oula[i];
31     }
32 }
33 
34 
35 int gcd(int a, int b) {
36     return b == 0 ? a : gcd(b, a % b);
37 }
38 
39 void solve(ll num, int x) { //查找分母为x时,第num个分子,打印输出分数
40     int i;
41     if (x == 1) { //特别处理分母为1的情况
42         num--;
43         i = 0;
44     }
45     for (i = 1; i <= x && num; i++) {
46         if (gcd(i, x) == 1) {
47             num--;
48         }
49     }
50     printf("%d/%d\n", i - 1, x);
51 }
52 
53 int main() {
54     ll n;
55     init();
56     while (scanf("%lld", &n) && n != 0) {
57         int x = upper_bound(sum, sum + N, n) - sum; //返回大于n的第一个元素下标
58         int y = lower_bound(sum, sum + N, n) - sum; //返回不小于n的第一个元素下标
59         if (x != y) //处理边界情况,确保x始终为分母大小
60             x--;
61         ll temp = n - sum[x - 1]; //在分母为x的这个区间里,属于第几个
62         solve(temp, x);
63     }
64     return 0;
65 }

 

posted @ 2021-01-25 20:19  巨大力选手  阅读(136)  评论(0)    收藏  举报