小x的质数
题目描述
小 X 是一位热爱数学的男孩子,在茫茫的数字中,他对质数更有一种独特的情感。小 X 认为,质数是一切自然数起源的地方。
在小 X 的认知里,质数是除了本身和 11 以外,没有其他因数的数字。
但由于小 X 对质数的热爱超乎寻常,所以小 X 同样喜欢那些虽然不是质数,但却是由两个质数相乘得来的数。
于是,我们定义,一个数是小 X 喜欢的数,当且仅当其是一个质数,或是两个质数的乘积。
而现在,小 X 想要知道,在 LL 到 RR 之间,有多少数是他喜欢的数呢?
输入格式
第一行输入一个正整数 QQ,表示询问的组数。
接下来 QQ 行。包含两个正整数 LL 和 RR。保证 L \le RL≤R。
输出格式
输出 QQ 行,每行一个整数,表示小 X 喜欢的数的个数。
数据范围与约定
样例
样例解释 1
66 以内的质数有 2,3,52,3,5,而 4=2 * 2,6 = 2 * 34=2∗2,6=2∗3。因此 2,3,4,5,62,3,4,5,6 都是小 X 喜 欢的数,而 1 不是。
样例输入1
1 1 6
样例输出1
5
样例输入2
10 282 491 31 178 645 856 227 367 267 487 474 697 219 468 582 792 315 612 249 307
样例输出2
97 78 92 65 102 98 114 90 133 29
样例输入3
10 20513 96703 15236 86198 23185 78205 40687 48854 42390 95450 63915 76000 36793 92543 35347 53901 44188 76922 82177 90900
样例输出3
24413 23001 17784 2669 16785 3833 17712 6028 10442 2734
code
1 #include<cstdio> 2 #include<cmath> 3 4 const int MAXN = 10000100; 5 6 bool lk[MAXN],noprime[MAXN]; 7 int prime[MAXN]; 8 int sum[MAXN]; 9 10 int read() { 11 int x = 0,f = 1;char ch = getchar(); 12 for (; ch<'0'||ch>'9'; ch = getchar()) 13 if (ch=='-') f = -1; 14 for (; ch>='0'&&ch<='9'; ch = getchar()) 15 x = x*10+ch-'0'; 16 return x*f; 17 } 18 19 int main() { 20 21 int tot = 0; 22 23 for (int i=2; i<=10000000; i++) { 24 if (!noprime[i]) { 25 prime[++tot]=i; 26 lk[i] = true; 27 for (int j=1; j<=tot && i*prime[j]<=10000000; j++) { 28 noprime[i*prime[j]] = true; 29 lk[i*prime[j]] = true; 30 } 31 } 32 else { 33 for (int j=1; j<=tot&&i*prime[j]<=10000000; j++) { 34 noprime[i*prime[j]] = true; 35 if(i % prime[j] == 0) break ; 36 } 37 } 38 } 39 40 for (int i=1; i<=10000000; ++i) { 41 if (lk[i]) sum[i] = sum[i-1]+1; 42 else sum[i] = sum[i-1]; 43 } 44 45 int L,R,q = read(); 46 while (q--) { 47 L = read();R = read(); 48 printf("%d\n",sum[R]-sum[L-1]); 49 } 50 51 return 0; 52 }