Description
给定区间[L,R] (L<=R<=2147483647,R-L<=1000000),请计算区间中素数的个数。
Input
两个数L和R
Output
一行,区间中素数的个数。
题解
看到题目,很水啊。但一看到L,R的范围,太恐怖了!。
数据范围之大,所以不能一个一个枚举,用筛素来快速求出素数。
因为L,R<=2147483647 所以不能把1到2147483647-1的素数都求一个遍,可以先把sqrt(R)的素数求出来,然后筛素。(这46341的来源)为什么是sqrt(R),因为如果大于sqrt(R)的数把R筛出来了,那么R早就被小于sqrt(R)的数筛出来了.
那么对于R很大,数组不好开那么大,所以可以把L和R压到一个1000000的区间里是一样的,因为一定用L到R的数把区间里的数筛出来。
代码
var
x,y,n,ans:longint;
b:array[0..1000001] of boolean;
s:array[0..46341] of boolean;
a:array[0..10001] of longint;
procedure init;
var
j,i:longint;
begin
readln(x,y);
n:=y-x+1;
fillchar(s,sizeof(s),true);
s[1]:=false;
for i:=2 to 46341 do
if s[i] then
begin
for j:=2 to 46341 div i do
s[i*j]:=false;
inc(a[0]);
a[a[0]]:=i;
end;
if y<=46341 then
begin
for i:=1 to a[0] do
if (a[i]<=y) and (a[i]>=x) then
inc(ans);
write(ans);
halt;
end;
end;
procedure main;
var
i,j:longint;
begin
fillchar(b,sizeof(b),true);
for i:=1 to a[0] do
for j:=x div a[i] to y div a[i] do
if a[i]*j-x+1>=0 then b[a[i]*j-x+1]:=false;
if x<=46341 then
for i:=x to 46341 do
if s[i] then inc(ans);
for i:=1 to n do
if b[i] then inc(ans);
write(ans);
end;
begin
init;
main;
end.