素數密度 Standard IO

2021-09-02 23:59:49 字數 1619 閱讀 9970

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...