Description
小X 是一位热爱数学的男孩子,在茫茫的数字中,他对质数更有一种独特的情感。小X 认为,质数是一切自然数起源的地方。
在小X 的认知里,质数是除了本身和1 以外,没有其他因数的数字。
但由于小X 对质数的热爱超乎寻常,所以小X 同样喜欢那些虽然不是质数,但却是由两个质数相乘得来的数。
于是,我们定义,一个数是小X 喜欢的数,当且仅当其是一个质数,或是两个质数的乘积。
而现在,小X 想要知道,在L 到R 之间,有多少数是他喜欢的数呢?
在小X 的认知里,质数是除了本身和1 以外,没有其他因数的数字。
但由于小X 对质数的热爱超乎寻常,所以小X 同样喜欢那些虽然不是质数,但却是由两个质数相乘得来的数。
于是,我们定义,一个数是小X 喜欢的数,当且仅当其是一个质数,或是两个质数的乘积。
而现在,小X 想要知道,在L 到R 之间,有多少数是他喜欢的数呢?
Input
第一行输入一个正整数Q,表示询问的组数。
接下来Q 行。包含两个正整数L 和R。保证L≤R。
接下来Q 行。包含两个正整数L 和R。保证L≤R。
Output
输出Q 行,每行一个整数,表示小X 喜欢的数的个数。
solution
大家学习一个东西,叫做线性筛,时间复杂度为O(n)。
点这里→→→→→→→→↑↑↑←←←←←←←←点这里
理解之后,这题O(1)过。
代码
const p=10000000; var n,l,r,nm:longint; sum,prime,bo,boo:array [0..10000001] of longint; procedure try1; var i,j:longint; begin fillchar(bo,sizeof(bo),0); fillchar(boo,sizeof(boo),0); fillchar(sum,sizeof(sum),0); nm:=0; for i:=2 to p do if bo[i]=0 then begin inc(nm); prime[nm]:=i; j:=1; boo[i]:=1; while (j<=nm) and (i*prime[j]<=p) do begin bo[i*prime[j]]:=1; boo[i*prime[j]]:=1; inc(j); end; end else begin j:=1; while (j<=nm) and (i*prime[j]<=p) do begin bo[i*prime[j]]:=1; if i mod prime[j]=0 then break; inc(j); end; end; for i:=1 to p do sum[i]:=sum[i-1]+boo[i]; end; procedure init; var i:longint; begin readln(n); for i:=1 to n do begin readln(l,r); writeln(sum[r]-sum[l-1]); end; end; begin assign(input,'prime.in'); assign(output,'prime.out'); reset(input); rewrite(output); try1; init; close(input); close(output); end.