由素數篩法到尤拉函式(尤拉函式,線性篩)

2022-03-19 20:49:04 字數 1503 閱讀 7569

蒟蒻最近準備狂補數學啦tat

基於篩素數,可以同時快速求出尤拉函式。於是蒟蒻準備從這裡入手,整理一下實現的思路。

傳統篩素數的做法(埃式篩)是,利用已知的素數,去篩掉含有此質因子的合數,十分巧妙。由於不是本文的重點,就只貼一下**吧

#include#include#define r register int

const int n=100000000,sq=sqrt(n);

bool f[n];

int main(){

r i,j;

for(i=2;i<=sq;++i){

if(f[i])continue;

for(j=i<<1;j複雜度不會證,不過較近似於線性(大概是\(o(n\log\log n)\)的樣子)。

實際上蒟蒻打了個表,n與篩的次數大概有這樣的關係

為什麼是近似的呢?因為每個合數會被其多個質因子都篩一遍,所以並不是嚴格的。

於是我們要想辦法讓每個合數只被篩掉一次。如何實現呢?我們可以讓每個合數都只被其最小質因子篩掉(尤拉篩)。

與上面相比,這種新的更加優秀的寫法有了較大的變化。**如下,可結合注釋理解,也不多討論。

#include#include#define r register int

const int n=100000000,b=n>>1;

bool f[n];

int pr[b];

int main(){

r i,j,p=0;

for(i=2;i<=b;++i){

if(f[i])

for(j=1;j<=p&&i*pr[j]實際執行\(n=10^8\)比上面那種寫法快一半。

對乙個正整數\(x\)定義尤拉函式\(\phi(x)\),為\([1,x]\)中與\(x\)互質的整數個數。

幾個基本內容(下面定義\(p\)為質數):

\(\phi(1)=1\),這個沒啥好說的,因為本來就定義\(1\)與\(1\)互質

\(\phi(p)=p-1\),也是很顯然的,由質數定義得出

這樣的話,是不是可以像埃式篩一樣,通過某個質數篩去質因子含這個數的合數的同時,計算出這個合數的尤拉函式值呢?好像是不行的,因為可能兩個數的商的尤拉函式值還沒求出來。

這時候,更好的尤拉篩又派上了用場。列舉\(x\)再列舉質數\(p\),這時候\(\phi(x)\)和\(\phi(p)\)肯定都求出來啦,那麼\(\phi(x*p)\)當然也就求出來啦。

#include#define r register

const int n=1000001;

int pr[n],phi[n];

bool f[n];

int main(){

r int n,i,j,k,p=0;

phi[1]=1;//內容1

for(i=2;i一道模板題及其sol

尤拉函式 素數篩

尤拉發現求小於等於n的正整數中有多少個數與n互質可以用這個公式 euler x x 1 1 p1 1 1 p2 1 1 p3 1 1 p4 1 1 pn 其中p1,p2 pn為x的所有素因數,x是不為0的整數。euler 1 1 唯一和1互質的數就是1本身 尤拉公式的延伸 乙個數的所有質因子之和是e...

尤拉函式尤拉篩

尤拉函式求小於等於n與n互質的數的個數 複習時發現這個知識點竟然沒有整理 n為素數即為n 1 除了其本身 n為素數的倍數 ola sushu j i ola i sushu j else ola sushu j i ola i sushu j 1 include include include in...

AcWing 篩法求尤拉函式 篩法 尤拉函式

時 空限制 1s 64mb 給定乙個正整數n,求1 n中每個數的尤拉函式之和。共一行,包含乙個整數n。共一行,包含乙個整數,表示1 n中每個數的尤拉函式之和。1 n 10 6 題意 求1 n中每個數的尤拉函式之和。思路 在這個題目中我們不能直接分別去求1 n之間的尤拉函式,會超時,所以我們就可以根據...