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
to46341
doif s[i] then
begin
for j:=2
to46341
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
doif s[i] then inc(ans);
for i:=1
to n do
if b[i] then inc(ans);
write(ans);
end;
begin
init;
main;
end.
codevs 3223 素數密度
題目描述 description 給定區間 l,r l r 2147483647,r l 1000000 請計算區間中素數的個數。輸入描述 input description 兩個數l和r 輸出描述 output description 一行,區間中素數的個數 樣例輸入 sample input 2...
CodeVS3223 素數密度
兩個數l和r 一行,區間中素數的個數 2 11 詳見試題 篩出2 sqrt r 中的素數,然後用這些數篩l r中的素數 pri存2 sqrt r 中的素數 dpri 存r l中的素數 向左平移l個 include include includeusing namespace std bool pri...
NOIP模擬題 素數密度
問題描述 給定區間 l,r l r 2147483647,r l 1000000 請計算區間中素數的個數。輸入資料 兩個數l和r 輸出資料 一行,區間中素數的個數。樣例輸入 2 11 樣例輸出 5l和r範圍很大,但區間長度反而很小。考慮平移區間,將l和r的下標縮小 l是0,l 1是1 篩法求素數 1...