标签:
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\n", dp[a] - dp[b]);
66 }
67
68 return 0;
69 }
70
71 /*
72 3
73 3 1
74 6 3
75 5000000 4999995
76 */
DP+埃氏筛法 Codeforces Round #304 (Div. 2) D. Soldier and Number Game
标签:
原文地址:http://www.cnblogs.com/Running-Time/p/4530593.html