乙個對單個n有效的方法:
f[n]表示n以內的素數個數
c[i]表示第i個素數
g[n][m]表示n以內不被c[1..m]整除的數的個數
(1)
f[n]=f[sqrt(n)]+g[n][f[sqrt(n)]]-1
//大於sqrt(n)的合數必然會被小於等於sqrt(n)的素數去掉,而1要去掉
(2)
g[n][m]=g[n][m-1]-g[n/c[m]][m-1]
//n以內不被前m-1個素數整除的數,那麼還要減去被c[m]整除而不被c[1..m-1]整除的 對於g
[n][
m]的計算的優化(很有用,當n在我們預處理的範圍maxn中時):
1)若f[n
]<=
m 說明n內除了1之外所有數都可以被c[1..m]整除掉(return 1)
2)若f[n
√]<=
m 說明只有n內的素數#可能#滿足g[n][m],那麼要去掉m個素數在加上1(return f[n]+1-m)
洲閣篩是「對形式較為一般的積性函式給出一種求和演算法」
積性函式:
設n的質因數分解為:n=
πki=
1p[i
]c[i
] (即n=
p[1]
c[1]
×p[2
]c[2
]×..
.×p[
k]c[
k])
有積性函式f(n)滿足:
·當n為質數時,f(
n)=g
(n)
·當n=pc
時,f(
pc)=
t(pc
) ·其他情況根據積性函式的積性,f(
n)=π
ki=1
f(p[
i]c[
i]) (即f(
n)=f
(p[1
]c[1
])×f
(p[2
]c[2
])×.
..×f
(p[k
]c[k
]))
對於euler函式,g(
p)=p
−1,t
(pc)
=(p−
1)p(
c−1)
對於莫比烏斯函式,g(
p)=−
1,t(
pc)=
0 拋磚引玉:
有函式f(n
)=πk
i=1(
p[i]
c[i]
+d)
求字首和,利用之前的表示方法,g(
p)=p
+d,t
(pc)
=pc+
d 轉化1:
根據引理:對於乙個在n以內的數x,x最多擁有乙個大於n√
的質因子
那麼f(x)可以分兩類考慮:
·x沒有大於n√
的質因子
·x有乙個大於n√
的質因子 得到∑
ni=1
f(i)
=∑x≤
n且x沒
有大於n
√的質因
子f(x
)×(1
+∑n√
[nx]
且p為質
數g(p
))觀察得到,後面乘上的係數只與[n
x]有關,所以不同的係數只有o(
n√) 種,可以根據[n
x]的取值將f(x)分成o(
n√) 段,每一段對應著一樣的係數
於是需要處理的就是兩部分: ·∑
n√[nx]
且p為質
數g(p
) ·∑
x沒有大
於n√的
質因子f
(x)
g(p)的計算
設不超過n√
的質數總共有m個,公升序排序為c[1..m]
設g[k][n][m]表示n內與前m個質數互質的所有數的k次冪之和,當m=0時就是自然數冪求和
當i>=1時:g[
k][n
][m]
=g[k
][n]
[m−1
]−c[
m]k×
g[k]
[n/c
[m]]
[m−1
] 最終得到的g[k][n][m]-1即為[1,n]範圍內大於n√
的質數的k次冪之和
根據兩個引理:
·設正整數x,y,a,b,其中a,
b≤x,
y=[x
a]那麼有[y
b]=[
xab]
·對於所有i≤
n√,[ni
] 的取值有o(
n√) 種
對於所有
i,[ni
] 的取值也有o(
n√) 種
得到計算g[k][i][j]時,i的狀態數只有o(
n√) 種,且這些狀態剛好為需要被計算的g(p)之和
樸素實現
樸素的實現這乙個遞推式需要依次列舉質數p[i],對每乙個狀態進行計算。
對每乙個[n
x]中有多少個質數需要轉移,時間複雜度o(
nlog
n)優化
當c[j+1]>i時,g[k][i][j]=1(因為只有1滿足要求)
所以當c[j
]2>i≥
c[j]
時,即l=
[ic[
j]]j]
時有 g[
k][l
][j−
1]=1
得g[k][i
][j]
=g[k
][i]
[j−1
]−c[
j]k×
g[k]
[i/c
[j]]
[j−1
]=g[
k][i
][j−
1]−c
[j]k
於是當c[
j]2>
i 時的計算可以直接省掉
那麼對於每一組[n
x]只需要轉移不超過[n
x]−−
−√的質數,利用積分,可以得到: o(
∫n√0
nx√d
xlog
n)=o
(n34
logn
) f(x)的計算 由於[
nx] 值相同的f(x)需要乘的係數是一樣的,可以直接用[n
x]來表示狀態
同樣設不超過n√
的質數總共有m個,公升序排序為c[1..m]
設f[i][j]表示只包含前j種質因子,且[n
x]=i
的f(x)之和,其中f[n][0]=1
類似的,第一維中只有o(
n√) 種狀態。
樸素實現
由f[i][j-1]轉移過來,那麼列舉冪次t,設l=
[ic[
j]t]
,那麼:
·當t>1時,對f[
l][j
] 的貢獻為t(
c[j]
t)×f
[i][
j−1]
·當t=1時,對f[
l][j
] 的貢獻為g(
c[j]
)×f[
i][j
−1]
注意,上面看上去是反過來遞推的,這是因為,我們的第一維是指[n
x]複雜度與g(p)的樸素實現類似。
優化 在g(p)的計算中省去了c[
j]2>
i 的計算,這裡同樣考慮相似的優化措施。 當[
nx] 不超過n√
時有:1+
∑n√<
p<[n
x]且p
為質數g
(p)=
1 而最後的計算答案的式子為:∑n
i=1f
(i)=
∑x≤n
且x沒有
大於n√
的質因子
f(x)
×(1+
∑n√[nx]
且p為質
數g(p
)) 當
c[j]
2>y=
[nx]
時,[y
c[j]
]j]≤n
√ ,所以狀態y最多只能用乙個超過c[j]的質數轉移,並且轉移後的值的答案的貢獻係數一定為1
優化後的策略如下:
·對於乙個質數c[i],只考慮y≥
c[i]
2 的情況 ·設l
=[yc
[i]t
] ,假如
li]2 那麼這個狀態在之後會被忽略,需要現在計算他對答案的貢獻,也就是統計[c
[i+1
],l]
範圍內的g(p)之和
·維護每個狀態最後一次轉移時的c[i],統計被忽略的那一段g(p)之和
複雜度類似
撒花!!!!!!!!!!
先留個坑先。
loj 6235 區間素數個數(洲閣篩)
題面在這裡 之前寫過一發 然後這次作為複習又重新寫了一遍 然後發現比上一次快了2000 ms?儘管依然很慢 我好像沒加什麼優化啊 許是loj評測機效能變佳 洲閣篩模板。裡有詳細的注釋。注意初始化 並不針對這道題,這題不初始化也沒事因為只有一組資料,但是假如有多組或使用了多次cal的情況就要注意 in...
演算法學習 線篩
那些年普通的篩法 for i 2 i sqrt n i if bz i for j 2 j i其實可以優化 for i 2 i sqrt n i if bz i for j i j i bz i j 0 因為像3 2 和 2 3這樣的重複了 其實優化過後就成了erotosthenes演算法o n l...
微信小程式 二 語法學習
語法學習 一 模板語法 1.資料 pages block block.js 本幢事宜 2.模版 view msg view view num view view isgirl view view person view view age view view data num 自定義屬性使用 view...