【題目鏈結】:
【題意】
【題解】
可以在o(n)的複雜度內求出1..n裡面的所有素數;
當然受空間限制,n可能也就是幾百萬的樣子吧;
再低一點的話用樸素的篩法都能過了;
它的思路主要是;
抓住每個合數的最小的質因數是唯一的這一點;
然後避免每個合數被多次計算到;
因此每次列舉的都是質因數的倍數;
同時i%prim[j]==0直接break掉那點也很巧妙;
這裡找到了break掉的原理↓↓
/*
演算法最難理解的是第七行:
當peimer[j]是i的因子的時候,退出迴圈,不再進行剔除操作;
這麼做的原因如下:首先peimer[j]是i的最小質因數,因為j是從0開始的;
其次,我們可以肯定的說,i已經無需再去剔除prime[j']*i (j'>j) 形式的合數了,這是因為,prime[j']*i可以寫成
prime[j']*(prime[j]*k)
=prime[j]*(prime[j']*k),
也就是說所有的prime[j']*i將會被將來的某個i'=prime[j']*k剔除掉,當前的i已經不需要了。
*/
【number ofwa】
0 【完整**】
#include
using
namespace
std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ll long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ms(x,y) memset(x,y,sizeof x)
typedef pair pii;
typedef pairpll;
const
int dx[9] = ;
const
int dy[9] = ;
const
double pi = acos(-1.0);
const
int n = 1e6+100;
bool iszs[n];
vector
zsb;
int n;
int main()
}cout
<< zsb.size() << endl;
return
0;}
hihocoder 數論二 Eular質數篩法
時間限制 10000ms 單點時限 1000ms 記憶體限制 256mb 描述小ho 小hi,上次我學會了如何檢測乙個數是否是質數。於是我又有了乙個新的問題,我如何去快速得求解 1,n 這個區間內素數的個數呢?小hi 你自己有什麼想法麼?小ho 有!我一開始的想法是,自然我們已經知道了如何快速判定乙...
Eular質數篩法
任意乙個正整數k,若k 2,則k可以表示成若干個質數相乘的形式。eratosthenes篩法中,在列舉k的每乙個質因子時,我們都計算了一次k,從而造成了冗餘。因此在改進演算法中,只利用k的最小質因子去計算一次k。而在其基礎上改進的eular篩法,其偽 為 isprime true primelist...
Eular質數篩法 尤拉篩
相比於時間複雜度為 o n lgn 2 的埃氏篩法,eular 質數篩法就顯得非常短小精悍。尤拉篩的時間複雜度為 o n 是一種空間換取時間的演算法。一 空間需求 尤拉篩需要兩個陣列 prime,用來儲存素數。is prime,用來表示 i i n 是否為質數。二 步驟 memset is prim...