最近學習了一種篩素數的方法,能夠在 o(n) 的時間內完成。
這個演算法的核心思想是:每乙個合數可以被唯一地表示成它的乙個最小質因子和另外乙個數的乘積。證明略。
void init()
for (ll j=0;j*prime[j]*prime[j]]=1;
if(i%prime[j])
ph[i*prime[j]]=ph[i]*(prime[j]-1);
else
} }
}
通俗的說,就是對於每乙個質數p,列舉i,刪除i*p^1, i*p^2, i*p^3, …。
這個是篩素數的乙個很原始的方案,也就是把質數的所有倍數刪掉。看起來很暴力,但是很容易證明它的正確性,更容易證明它的時間複雜度是o(n)的:因為每乙個元素最多被刪除一次,並且沒有新的元素插入集合中!
同時,也可以線性的求莫比烏斯函式
void init_mu()
for(int j=0; j*prime[j]*prime[j]]=1;
if(i%prime[j])
mu[i*prime[j]]=-mu[i];
else
} }
}
void init()
for (ll j=0;j*prime[j]*prime[j]]=1;
if(i%prime[j])
else
} }
}
helenkeller
2016.7.9
線性篩素數 尤拉函式 莫比烏斯函式
常用的兩種素數篩法見部落格 http 這裡詳講線性篩,演算法複雜度o n 這個演算法的核心思想是 每乙個合數可以被唯一地表示成它的乙個最小質因子和另外乙個數的乘積。證明略。先上 const int n 1000000 int phi n prime n mu n bool vis n void in...
線性篩素數 尤拉函式 莫比烏斯函式
判斷素數 對於n,分別列舉1 sqrt n 最樸素的素數篩 埃拉託斯特尼篩法 sieve of eratosthenes 1 int primes maxn ent 0 2 bool isprime maxn 3void getprime 414 15 複雜度 nlglgn 尤拉篩 每個合數只會被乙...
尤拉篩(線性篩)求莫比烏斯函式
篩法我們肯定都不陌生,用來求一定序列內素數個數的方法麻,但在學習完埃氏篩法後 如果沒學過可以去學一下再看 我們發現它似乎做了很多多餘的操作,乙個數會被他的質所有篩 一遍,但我們本質上篩一遍就夠了,所以我們有沒有什麼方法去優化它呢?尤拉篩隨之而出,尤拉篩的特點便是乙個數隻會被它的最小質因子篩一遍,其它...