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
n2.當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,有logn
\log n
logn
個質因子,而根據質數分布的稀疏度,大概列舉完每個質因子需要nln
n\sqrt n\over \ln
lnnn
的時間,因此,最壞最壞的情況的時間複雜度為o(n
+m
nlogn
lnn)
o(\sqrt n +m\cfrac} )
o(n+m
lnnn
logn
)而最壞的情況顯然不能發生,所以真正的時間複雜度要遠遠小於o(n
+m
nlogn
lnn)
o(\sqrt n +m\cfrac} )
o(n+m
lnnn
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...