素数密度 (Standard IO)

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.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值