DP+埃氏筛法 Codeforces Round #304 (Div. 2) D. Soldier and Number Game

题目传送门

 1 /*
 2     题意:b+1,b+2,...,a 所有数的素数个数和
 3     DP+埃氏筛法:dp[i] 记录i的素数个数和,若i是素数,则为1;否则它可以从一个数乘以素数递推过来
 4                     最后改为i之前所有素数个数和,那么ans = dp[a] - dp[b];
 5     详细解释:http://blog.csdn.net/catglory/article/details/45932593
 6 */
 7 #include <cstdio>
 8 #include <algorithm>
 9 #include <cstring>
10 #include <map>
11 #include <cmath>
12 using namespace std;
13 
14 typedef long long ll;
15 
16 const int MAXN = 5e6 + 10;
17 const int INF = 0x3f3f3f3f;
18 int prime[MAXN];
19 bool is_prime[MAXN];
20 ll dp[MAXN];
21 
22 int seive(void)
23 {
24     for (int i=0; i<=5e6; ++i)    is_prime[i] = true;
25     is_prime[0] = is_prime[1] = false;
26     int p = 0;
27     for (int i=2; i<=5e6; ++i)
28     {
29         if (is_prime[i])
30         {
31             prime[++p] = i;
32             for (int j=2*i; j<=5e6; j+=i)    is_prime[j] = false;
33         }
34     }
35 
36     return p;
37 }
38 
39 void solve(void)
40 {
41     int p = seive ();
42     for (int i=2; i<=5e6; ++i)
43     {
44         if (is_prime[i])    {dp[i] = 1;    continue;}
45         for (int j=1; j<=p; ++j)
46         {
47             if (i % prime[j] == 0)
48             {
49                 dp[i] = dp[i/prime[j]] + 1;    break;
50             }
51         }
52     }
53 
54     for (int i=3; i<=5e6; ++i)    dp[i] += dp[i-1];
55 }
56 
57 int main(void)        //Codeforces Round #304 (Div. 2) D. Soldier and Number Game
58 {
59     solve ();
60     int t;    scanf ("%d", &t);
61     while (t--)
62     {
63         int a, b;
64         scanf ("%d%d", &a, &b);
65         printf ("%I64d
", dp[a] - dp[b]);
66     }
67 
68     return 0;
69 }
70 
71 /*
72 3
73 3 1
74 6 3
75 5000000 4999995
76 */
编译人生,运行世界!
原文地址:https://www.cnblogs.com/Running-Time/p/4530593.html