• SPOJ


    TAP2013H - Horace and his primes

    no tags 

    [The original version of this problem (in Spanish) can be found athttp://www.dc.uba.ar/events/icpc/download/problems/tap2013-problems.pdf]

    Horace likes to play writing natural numbers in the blackboard in his bedroom. One of his favourite games consists in first writing a numbern, then the sum of all the different prime numbers that dividen, and so on until the number written on the board becomes a prime number. For example, if Horace begins writing the numbern = 90, because90 = 2 × 32 × 5 the next number to be written will be2 + 3 + 5 = 10; then, as 10 = 2 × 5 Horace will write the number2 + 5 = 7; finally, because7 is a prime number the game will end here.

    Formally, in this game each natural number n >= 2 defines a sequence whose first element is n, and each new element is the sum of all the prime numbers that divide the previous element in the sequence. The order of the game is the position of the first prime number in the sequence, and coincides with the total number of numbers written on the blackboard one the game has ended. In the example from the previous paragraph, with n = 90 the order of the game is K = 3, because the numbers that are written will be 90, 10 and 7.
    Now, not all games are equally entertaining to Horace, and in this case he prefers to begin by writing a number n such that the order of the corresponding game is a particular value K. Horace would like to know how many different values of n between A and B inclusive satisfy this condition, but because he does not know how to code he needs someone to do this calculation for him. Can you help him?
    INPUT
    The first line contains an integer P which indicates the number of questions Horace wants to ask you (1 <= P <= 10^5). Each of the next P lines describes a question using three integer numbers A, B and K, which mean that Horace would like to know how many different values of n satisfy that A <= n <= B and the order of the game beggining with n is K (2 <= A <= B <= 10^6 and 1 <= K <= 10^6).
    OUTPUT
    You should print P lines, each one containing an integer number with the answer to one of the questions made by Horace, in the order in which they appear in the input.

    Formally, in this game each natural number n ≥ 2 defines a sequence whose first element isn, and each new element is the sum of all the prime numbers that divide the previous element in the sequence. The order of the game is the position of the first prime number in the sequence, and coincides with the total amount of numbers written on the blackboard once the game has ended. In the example from the previous paragraph, withn = 90 the order of the game isK = 3, because the numbers that are written will be90,10 and 7.

    Now, not all games are equally entertaining to Horace, and in this case he prefers to begin by writing a numbern such that the order of the corresponding game is a particular valueK. Horace would like to know how many different values of n between A and B inclusive satisfy this condition, but because he does not know how to code he needs someone to do this calculation for him. Can you help him?

    Input

    The first line contains an integer P which indicates the number of questions Horace wants to ask you (1 ≤ P ≤ 105). Each of the nextP lines describes a question using three integer numbersA, B and K, which mean that Horace would like to know how many different values ofn satisfy thatA ≤ n ≤ B and the order of the game beginning withn isK (2 ≤ A ≤ B ≤ 106 and1 ≤ K ≤ 106).

    Output

    You should print P lines, each one containing an integer number with the answer to one of the questions made by Horace, in the order in which they appear in the input.

    Example 1

    Input:
    1
    90 90 3
    
    Output:
    1
    
    

    Example 2

    Input:
    5
    2 9 1
    2 9 2
    800 810 4
    999999 1000000 2
    100000 1000000 1000000
    
    Output:
    4
    4
    5
    2
    0
     


    题意:定义f[i] 为 i 的所有素因子的和(不重复计算),g[i] = f(f(i)) 即f[i]的迭代次数(直到i为素数为止,因为此时 f[i] = i)。

               现在给定 a, b, p问你a, b之间有多少个数的g[i] = p;

    题解:根据数据范围可以发现1e6以内的数最多迭代12次就可以结束。那么我们可以将所有次数12 以内的数字打表求出来。

               然后在这个表里面二分求解答案即可。 注意打表的技巧。

               1、筛素数的时候可以把每个数的 f[i] 求得。

               2、从小到大遍历数字 2-1e6的时候,可以求得 g[i] 。i为素数时 g[i] = 1,否则 g[i] = g[f[i]];

                   (因为 f[i]  <=  i,且是从小到大遍历的,所有比 i 小的 g[i] 都已经求得)

    代码:

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <map>
     6 #include <vector>
     7 #include <queue>
     8 #include <list>
     9 #include <cstdio>
    10 #define rep(i,a,b) for(int (i) = (a);(i) <= (b);++ (i))
    11 #define per(i,a,b) for(int (i) = (a);(i) >= (b);-- (i))
    12 #define mem(a,b) memset((a),(b),sizeof((a)))
    13 #define FIN freopen("in","r",stdin)
    14 #define FOUT freopen("out","w",stdout)
    15 #define IO ios_base::sync_with_stdio(0),cin.tie(0)
    16 #define mid ((l+r)>>1)
    17 #define ls (id<<1)
    18 #define rs ((id<<1)|1)
    19 #define N 1000000+5
    20 #define INF 0x3f3f3f3f
    21 #define INFF 0x3f3f3f3f3f3f3f
    22 typedef long long ll;
    23 const ll mod = 1e8+7;
    24 const ll eps = 1e-12;
    25 using namespace std;
    26 
    27 int T,a,b,k,sum[N],g[N];
    28 bool isPrime[N];
    29 vector <int> ans[20];
    30 void fuc(){
    31     mem(isPrime, true);
    32     rep(i, 2, N-1){
    33         if(isPrime[i]){
    34             for(int j = i+i;j <= N-1;j += i){
    35                 isPrime[j] = false;
    36                 sum[j] += i;
    37             }
    38         }
    39     }
    40     rep(i, 2, N-1){
    41         if(isPrime[i])    g[i] = 1;
    42         else
    43             g[i] = g[sum[i]]+1;
    44         ans[g[i]].push_back(i);
    45     }
    46 }
    47 int main()
    48 {IO;
    49     //FIN;
    50     fuc();
    51     cin >> T;
    52     while(T--){
    53         cin >> a >> b >> k;
    54         if(k >= 13){
    55             cout << "0" << endl;
    56             continue;
    57         }
    58         int l = lower_bound(ans[k].begin(), ans[k].end(), a)-ans[k].begin();
    59         int r = upper_bound(ans[k].begin(), ans[k].end(), b)-ans[k].begin();
    60         cout << r-l << endl;
    61     }
    62     return 0;
    63 }
    View Code
  • 相关阅读:
    JavaSE Day11
    JavaSE Day10
    JavaSE Day9
    JavaSE Day8
    JavaSE Day7
    a
    js 操作 字符串
    委托的生明与使用
    T-SQL 的简单查询语句
    asp.net服务控件的生命周期
  • 原文地址:https://www.cnblogs.com/Jstyle-continue/p/6351921.html
Copyright © 2020-2023  润新知