zoukankan      html  css  js  c++  java
  • POJ_2478 Farey Sequence 【欧拉函数+简单递推】

    一、题目

    The Farey Sequence Fn for any integer n with n >= 2 is the set of irreducible rational numbers a/b with 0 < a < b <= n and gcd(a,b) = 1 arranged in increasing order. The first few are 
    F2 = {1/2} 
    F3 = {1/3, 1/2, 2/3} 
    F4 = {1/4, 1/3, 1/2, 2/3, 3/4} 
    F5 = {1/5, 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5} 

    You task is to calculate the number of terms in the Farey sequence Fn.

    Input

    There are several test cases. Each test case has only one line, which contains a positive integer n (2 <= n <= 10 6). There are no blank lines between cases. A line with a single 0 terminates the input.

    Output

    For each test case, you should output one line, which contains N(n) ---- the number of terms in the Farey sequence Fn. 

    Sample Input

    2
    3
    4
    5
    0

    Sample Output

    1
    3
    5
    9

    二、题意分析

    题意就是给你一个范围内的正整数N,让你去用1~N的数字去组合成Farey序列。关于Farey序列,依题意可知,就是1~N的数字中互素的a,b,其中a<b,就可以凑成一个a/b。然后问有多少个不同的a/b

    我们先看2,就一个,看3,发现2有的3肯定有,然后其余的就是与3互质的数与3凑成的a/b。再看4,3有的还是有,然后再加上与4互质的数与4凑成的a/b。依次递推下去。就是欧拉函数的前N项和。用一个数组累加保存下来,就是所有结果了,再用线性筛法去求欧拉函数(可以看我之前的欧拉函数学习笔记),速度绝对够。需要注意的是,结果增长的很快,需要用long long

    三、AC代码

      

    #include <iostream>
    #include <cstring>
    using namespace std;
    const int MAXN = 1e6+5;
    int Phi[MAXN], Prime[MAXN], nPrime;
    long long Ans[MAXN];
    
    void Euler()
    {
        memset(Phi, 0, sizeof(Phi));
        Phi[1] = 1;
        nPrime = 0;
        for(int i = 2; i < MAXN; i++)
        {
            if(!Phi[i]) //i为素数
            {
                Phi[i] = i - 1;
                Prime[nPrime++] = i;
            }
            for(int j = 0; j < nPrime && (long long)i*Prime[j] < MAXN; j++)
            {
                if(i%Prime[j])
                {
    
                    Phi[ i*Prime[j] ] = Phi[i]*(Prime[j]-1);
                }
                else
                {
                    Phi[ i*Prime[j] ] = Phi[i]*Prime[j];
                    break;
                }
            }
        }
        return;
    }
    
    void solve()
    {
        Euler();
        Ans[2] = Phi[2];
        for(int i = 3; i < MAXN; i++)
        {
            Ans[i] = Ans[i-1] + Phi[i];
        }
        return;
    }
    
    
    int main()
    {
        int N;
        solve();
        while(cin>>N && N)
        {
            cout << Ans[N] << endl;
        }
        return 0;
    }
    

      

  • 相关阅读:
    js操作
    函数知识点补充
    css---position
    css-浮动
    css-边界重叠以及边界塌陷
    css
    css文本类型操作
    POJ 2828 线段树活用
    POJ 3468 线段树
    POJ 3013 SPFA算法,邻接表的使用
  • 原文地址:https://www.cnblogs.com/dybala21/p/9747695.html
Copyright © 2011-2022 走看看