洛谷 P3383【模板】线性筛素数

题目大意:
如题,给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内)

时空限制:500ms 128M
数据规模:
对于30%的数据:
N<=10000,M<=10000
对于100%的数据:
N<=10000000,M<=100000

题解:
数学方法:
线性筛素数:
很多人都是找到一个素数,然后翻倍法,这种方法,通常的时间复杂度为:O(N log N)

不够高效,所以我们要优化!

即线性的去筛:
①一个数组表示i是否是素数,然后存一个素数表。

②每次将一个不是素数的i,*素数表数的数筛掉,因为
合数*素数=合数!这样i就被[1,i]内的素数给排掉了;
③对于一个枚举到的i,因为没被筛掉,则为素数,继续加入素数表。
这样的筛法,特别的高效,因为时间复杂度取决于素数的数量!
而数到后面素数也越来越少,所以素数表的枚举并不会花费太多的时间,注意素数表不能开太小!
时间复杂度:(NM) M极小,近乎O(N)
而这道题,就是个模版,大家可以去做一下,注意判断越界以及数组大小即可!

var
   a:Array [0..1000001] of longint;
   b:Array [0..10000001] of boolean;
   i,j,n,m:longint;

begin
    readln(n,m);
    b[1]:=true;
    for i:=2 to n do
      begin
           if not(b[i]) then
              begin
                   inc(a[0]);
                   a[a[0]]:=i;
              end;
           for j:=1 to a[0] do
           begin
              if i*a[j]>n then break;
              b[i*a[j]]:=true;
           end;
      end;
    for i:=1 to m do
      begin
           readln(j);
           if not(b[j])
              then writeln('Yes')
              else writeln('No');
      end;
end.

你可能感兴趣的:(pascal,线性筛素数)