SQH法求尤拉函式

2021-10-18 22:42:04 字數 2277 閱讀 4044

sqh法的由來

今日刷題時,遇到了乙個本蒟蒻想一下午也想不出來ac方法的題:p3601 簽到題

於100%的

資料,1

≤l≤r

≤1012

r−l≤

10

6對於100\%的資料,1≤l≤r≤10^ r−l≤10^6

對於100%

的資料,

1≤l≤

r≤10

12r−

l≤10

6發現這資料範圍不能(反正我是不會)用正常線性篩或者用通解公式來求,前者沒法開這麼大的陣列,後者的時間複雜度為o((

r−l)

r)

o((r-l) \sqrt)

o((r−l

)r​)

,於是乎,我就苦思冥想,用遞推法歪打正著的發明了一種新演算法來求尤拉函式

應用範圍:需要求尤拉函式的特別大,大於陣列能開的範圍

原理:

1.乙個大數n

nn只可能有乙個質因子大於n

\sqrt

n​2.當n

nn為質數,ϕ(p

)=p−

1\phi (p)=p-1

ϕ(p)=p

−13.當p

pp為質數,p∣n

p|np∣

n,i%p=

=0

i\%p==0

i%p==0

時,ϕ (p

∗i)=

=p∗ϕ

(i

)\phi (p*i)==p*\phi (i)

ϕ(p∗i)

==p∗

ϕ(i)

4.當p

pp為質數,p∣n

p|np∣

n,i%p!

=0

i\%p!=0

i%p!=0

時,ϕ (p

∗i)=

=(p−

1)∗ϕ

(i

)\phi (p*i)==(p-1)*\phi(i)

ϕ(p∗i)

==(p

−1)∗

ϕ(i)

提前求出1~n

\sqrt n

n​的質數不斷除以質因子,用遞迴把n化為質數,然後邊界回歸n-1,或者提前求出1~n

\sqrt n

n​的尤拉函式,當n小於n

\sqrt n

n​是,回歸即可

code:

#pragma comment(linker, "/stack:102400000,102400000")

/*************************

一定要加上面那一行!防止爆棧

*************************/

//f[n]=0說明n為質數,f[n]=1為合數

//p儲存質數

void

getprime()

for(

int j=

1;j<=cnt&&p[j]

*i<=

1000001

;++j)}}

}ull near

(ull num)

}ull searchphi

(ull num)

}}

時間複雜度:

設數的大小為n,要求m個數

求質數產生的o(n

)o(\sqrt n)

o(n​

)的時間不計,最壞的情況下質因子全為2,有log⁡n

\log n

logn

個質因子,而根據質數分布的稀疏度,大概列舉完每個質因子需要nln⁡

n\sqrt n\over \ln

lnn​n​​

的時間,因此,最壞最壞的情況的時間複雜度為o(n

+m

nlog⁡n

ln⁡n)

o(\sqrt n +m\cfrac} )

o(n​+m

lnn​n

​logn​

)而最壞的情況顯然不能發生,所以真正的時間複雜度要遠遠小於o(n

+m

nlog⁡n

ln⁡n)

o(\sqrt n +m\cfrac} )

o(n​+m

lnn​n

​logn​

)

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

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

篩法求尤拉函式

題目鏈結 題意 給定乙個正整數n,求1 n中每個數的尤拉函式之和。輸入格式 共一行,包含乙個整數n。輸出格式 共一行,包含乙個整數,表示1 n中每個數的尤拉函式之和。資料範圍 1 n 1e6 輸入樣例 6輸出樣例 12思路 如果直接用尤拉函式每次求一遍質因數的話就是o n sqrt n 的時間複雜度...

篩選法求尤拉函式

可以借鑑之前的求質因數分解的線性求法。對於要求1 n上的尤拉函式的和 尤拉函式定義如下 那麼 pi n 等於多少呢?由定義可以知道,尤拉函式和質因子的次方無關。因此這時候要分類討論 1.pi 如果是n的質因子,那麼 pi n pi n 2.如果不是,pi n pi n pi 1 pi 實現如下 in...