JZOJ5458 质数

Description

  小X 是一位热爱数学的男孩子,在茫茫的数字中,他对质数更有一种独特的情感。小X 认为,质数是一切自然数起源的地方。
  在小X 的认知里,质数是除了本身和1 以外,没有其他因数的数字。
  但由于小X 对质数的热爱超乎寻常,所以小X 同样喜欢那些虽然不是质数,但却是由两个质数相乘得来的数。
  于是,我们定义,一个数是小X 喜欢的数,当且仅当其是一个质数,或是两个质数的乘积。
  而现在,小X 想要知道,在L 到R 之间,有多少数是他喜欢的数呢?

Input

  第一行输入一个正整数Q,表示询问的组数。
  接下来Q 行。包含两个正整数L 和R。保证L≤R。

Output

  输出Q 行,每行一个整数,表示小X 喜欢的数的个数。

Sample Input

输入1:
  1
  1 6

输入2:
  10
  282 491
  31 178
  645 856
  227 367
  267 487
  474 697
  219 468
  582 792
  315 612
  249 307

输入3:
  10
  20513 96703
  15236 86198
  23185 78205
  40687 48854
  42390 95450
  63915 76000
  36793 92543
  35347 53901
  44188 76922
  82177 90900

Sample Output

输出1:
  5
  样例1解释:
  6以内的质数有2,3,5,而4=2*2,6=2*3。因此2,3,4,5,6都是小X 喜欢的数,而1 不是。

输出2:
  97
  78
  92
  65
  102
  98
  114
  90
  133
  29

输出3:
  24413
  23001
  17784
  2669
  16785
  3833
  17712
  6028
  10442
  2734

Data Constraint

Solution

  线性筛当然最好,这题普通筛法也可以过,用筛出的素数两两相乘求出喜欢的数。
 1 #include<cstdio>
 2 #include<cmath>
 3 using namespace std;
 4 int q,a[200000],b[200000],f[20000000],ma,d[10000000],l;
 5 int main()
 6 {
 7     scanf("%d",&q);
 8     for (int i=1;i<=q;i++)
 9     {
10         scanf("%d%d",&a[i],&b[i]);
11         if (b[i]>ma) ma=b[i];
12     }
13     for (int i=1;i<=ma;i++)
14         f[i]=1;
15     f[1]=0;
16     for (int i=2;i<=(int)sqrt((double) ma);i++)
17         for (int j=i;j<=ma/i;j++)
18             f[i*j]=0;
19     for (int i=2;i<=ma;i++)
20         if (f[i]==1) d[++l]=i;
21     for (int i=1;i<=l-1;i++)
22     {
23         int x=ma/d[i];
24         if (d[i]>x) break;
25         for (int j=i;j<=l;j++)
26             if (d[j]<=x) 
27                 f[d[i]*d[j]]=1;
28             else break;
29     }
30     for (int i=2;i<=ma;i++)
31         f[i]=f[i]+f[i-1];
32     for (int i=1;i<=q;i++)
33         printf("%d\n",f[b[i]]-f[a[i]-1]);
34 }
View Code

 

posted @ 2018-08-14 21:32  kasiruto  阅读(77)  评论(0编辑  收藏