日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

线性筛素数的实现与证明

發布時間:2023/12/3 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 线性筛素数的实现与证明 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

情境

大家應該都知道用nlogn的時間復雜度篩出[1,n]的所有素數,但是當n的范圍較大時,這個方法就不奏效了
今天我們談談素數的線性篩法,也就是用On的時間復雜度篩出[1,n]的所有素數

解析

nlog的算法之所以會慢,是因為它進行了很多重復的操作
比如,24可能就被篩了很多遍
那么我們優化復雜度的思路就是嘗試避免這些重復操作
也就是讓每個合數只被篩一次
怎么做呢?
我們讓每個合數只會被自己的最小質因數篩到
先看一下代碼:

代碼

void solve(){for(int i=2;i<=n;i++){if(v[i]==0){//還沒被篩到就是素數了prime[++tot]=i;v[i]=i;}for(int j=1;j<=tot;j++){ll now=prime[j];if(now>v[i]||now*i>n) break;//now*i>n就是超出范圍了,顯然也不要了v[now*i]=now;}}return; }

其中:

v[i]數組表示i的最小質因數
prime是素數表

代碼是怎么做的?
枚舉每一個數,再枚舉已有的素數,只要當前素數還不大于自己的最小質因數,就一直用它篩
這個算法可以說是:

巧奪天工

為什么這樣是對的呢?
接下來我們來證明一下這么做為什么就能不重不漏的篩出所有素數

證明

我們要證明兩部分:不重、不漏

不漏

會不會少篩一些合數?
假設有一個合數a,那么它一定有一個不等于它本身的最小質因數
也就是說,存在:

a=v*k(v為質數且v<k)

顯然v不會大于k的最小質因數,否則k的那個最小質因數就也是a的最小質因數了
那么我們在代碼中循環枚舉到k時,顯然就會用質數表中已經有的v把a篩出來

不重

考慮反證法
假設代碼過程中存在i與素數now,使得:

now*i=a;

且a的最小的質因數比i還小
不妨還設這個最小質因數為v
由于now已經是素數,所以這個v一定是i的一個因數
也就是說i存在一個質因數且小于now
那么now就一定比i的最小質因數大了
就會在前面的判斷中break出去
證畢

總結

以上是生活随笔為你收集整理的线性筛素数的实现与证明的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。