Linear Sieve Method for Prime Numbers

本文介绍了一种优化的素数筛选算法,通过避免重复删除合数来提高效率。利用每个合数都能分解为两个素数乘积的特性,仅需删除特定形式的合数即可找出所有素数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem description:When we calculate for prime numbers with a sieve method,we delete so many numbers which is not necessary repeatly.For instance,there is a number which consists of 3x7x17x23,and we delete it when we delete the multiples of 3 as we delete the same number when we delete the multiples of 7,17,and 23.Please write a program that will not do these jobs more than once.
   
Thinking: There is a factorization theorem:every composite number could be decomposed into the multiplication of some primer numbers.Hence,the number can be decomposed in the form of (both of p andq are prime numbers and p < q).Therefore,what we need to remove is:,,...and,i=1,2,3.....The value of p and q is the numbers which are not removed currently and in a sequence from small to large.It is easy to write the program.

 

#include <stdio.h>
  #define MAX 1000
  #define null1 0
  #define NEXT(x)  x=next[x]
  #define REMOVE(x) {   previous[next[x]]=previous[x];   \
                        next[previous[x]]=next[x];       \
                    }
  
  #define INITIAL(n)  { unsigned long i;                    \
                        for(i=2;i<=n;i++)                   \
                            previous[i]=i-1,next[i]=i+1;    \
                        previous[2]=next[n]=null1;           \
                      }
  
  int main()
  {
      unsigned long previous[MAX+1]={0};
      unsigned long next[MAX+1]={0};
      unsigned long prime,fact,i,mult;
      unsigned long n;
      unsigned long count=0;
      
      scanf("%lu",&n);
  
      INITIAL(n); //initial the array
  
      for(prime=2;prime*prime<=n;NEXT(prime))
      {
          for(fact=prime;prime*fact<=n;NEXT(fact)) 
          {
              for(mult=prime*fact;mult<=n;mult*=prime) 
                  REMOVE(mult);
          }
      }
      for(i=2;i!=null1;NEXT(i))
          printf("%lu ",i),count++;
      printf("\nThe sum of the prime numbers is %lu\n",count);
  }

Reference material: C语言名题精选百则技巧篇 in Chinese.

Cirno 和 Aya 在玩弹幕游戏。 游戏持续 � n 秒,Aya 有 � p 概率被 Cirno 的弹幕击中,每秒 Cirno 有 � q 概率被 Aya 的弹幕击中,两者可能同时被击中。 Cirno 想知道 � n 秒之后自己被击中的次数小于 Aya 被击中的次数的概率,答案对 10 9 + 7 10 9 +7 取模。 输入格式 第一行一个正整数 � n,表示游戏的事件。 第二行两个整数 � � , � � x p ​ ,y p ​ , � = � � � � p= y p ​ x p ​ ​ 表示 Aya 被击中的概率。 第三行两个整数 � � , � � x q ​ ,y q ​ , � = � � � � q= y q ​ x q ​ ​ 表示 Cirno 被击中的概率。 输出格式 输出一行一个整数,表示 Cirno 被击中的次数小于 Aya 被击中的次数的概率,答案对 10 9 + 7 10 9 +7 取模。 input1 运行 复制 2 1 2 1 2 output1 复制 812500006 input2 运行 复制 5 321378 36218731 854754 3427848 output2 复制 731320158 input3 运行 复制 10 32198321 78473474 48394948 93849348 output3 复制 654937644 input4 运行 复制 23333 12343218 87438433 43827474 94834931 output4 复制 528844215 数据范围 本题采用捆绑测试。 Subtask 1 1( 10 10 pts):保证 � ⩽ 10 n⩽10; Subtask 2 2( 20 20 pts):保证 � ⩽ 20 n⩽20; Subtask 3 3( 20 20 pts):保证 � ⩽ 5000 n⩽5000; Subtask 4 4( 20 20 pts):保证 � ⩽ 10 5 n⩽10 5 ; Subtask 5 5( 30 30 pts):无特殊限制。 对于 100 % 100% 的数据,保证 1 ⩽ � ⩽ 10 7 1⩽n⩽10 7 , 1 ⩽ � � ⩽ � � ⩽ 10 9 1⩽x p ​ ⩽y p ​ ⩽10 9 , 1 ⩽ � � ⩽ � � ⩽ 10 9 1⩽x q ​ ⩽y q ​ ⩽10 9
最新发布
07-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值