5458. 【NOIP2017提高A组冲刺11.7】质数

Description

小X 是一位热爱数学的男孩子,在茫茫的数字中,他对质数更有一种独特的情感。小X 认为,质数是一切自然数起源的地方。
在小X 的认知里,质数是除了本身和1 以外,没有其他因数的数字。
但由于小X 对质数的热爱超乎寻常,所以小X 同样喜欢那些虽然不是质数,但却是由两个质数相乘得来的数。
于是,我们定义,一个数是小X 喜欢的数,当且仅当其是一个质数,或是两个质数的乘积。
而现在,小X 想要知道,在L 到R 之间,有多少数是他喜欢的数呢?
 

Input

第一行输入一个正整数Q,表示询问的组数。
接下来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.
原文地址:https://www.cnblogs.com/zyx-crying/p/9460048.html