這篇部落格是一年前寫的……那時這東西好像還是個cai佬偷偷教我們的黑科技但現在似乎已經人盡皆知了……
cai佬說這東西叫做擴充套件埃氏篩,但似乎它和min25篩是乙個東西?
例題: loj6235 區間素數個數 設sum
(x
)sum(x)
sum(x)
表示小於等於x的素數個數。
假設我很蠢(這件事根本不用假設好嗎),連10以內的素數有哪些都不知道,只知道1不是素數。那麼我就會令sum
(x)=
x−
1sum(x)=x-1
sum(x)
=x−1
然後我就會做一些事情來扔掉合數,於是我從小到大處理素數。假設我在處理素數p
pp,並且想要扔掉sum
(i
)sum(i)
sum(i)
中以p為最小素因子的合數,我就會看向sum
(⌊ip
⌋)
sum(\lfloor \frac \rfloor)
sum(⌊p
i⌋)
,由於前期扔掉了一些數,這個裡面應該只有素數和素因子大於等於p的數,排除掉小於p的素數,剩下的數乘以p應該就是我們這一輪操作要扔掉的合數,也就是說,sum
(i)−
=sum
(⌊ip
⌋)−s
um(p
−1
)sum(i)-=sum(\lfloor \frac \rfloor)-sum(p-1)
sum(i)
−=su
m(⌊p
i⌋)
−sum
(p−1
) 設f 1(
x)=s
um(x
)f1(x)=sum(x)
f1(x)=
sum(
x),f 2(
x)=s
um(⌊
nx⌋)
f2(x)=sum(\lfloor \frac \rfloor)
f2(x)=
sum(
⌊xn
⌋)。f1和f2都只用開根號級別的空間。
那麼我們就可以靈活運用f1和f2來完成篩法了。
複雜度(聽說)可以近似擬合為o(n
34ln
n)
o(\frac}})
o(lnnn4
3)
#include
using
namespace std;
typedef
long
long ll;
const
int n=
1000005
;ll f1[n]
,f2[n]
,n,lim;
intmain()
printf
("%lld\n"
,f2[1]
);return0;
}
你已經學會了與素數玩耍,可以來水一道題了:loj6202 葉氏篩法
其實和上一題差不多,只是公式變成了sum
(x)−
=(su
m(⌊i
p⌋)−
sum(
p−1)
)×
psum(x)-=(sum(\lfloor \frac \rfloor)-sum(p-1)) \times p
sum(x)
−=(s
um(⌊
pi⌋
)−su
m(p−
1))×
p 此外,如果你不想寫高精的話,最後乙個樣例是過不去的…
#include
using
namespace std;
typedef
long
long ll;
typedef
double db;
const
int n=
1000005
;const db eps=
1e-12
;db f1[n]
,f2[n]
;ll l,r;
db sum
(ll x)
db query
(ll x)
return f2[1]
;}intmain()
例題:spoj-divcntk
…看**吧。關鍵思想是每個f(x)的貢獻是在處理x的最大質因子時算上的,x的最大質因子次數是1的時候可以用字首和快速處理,否則可以列舉處理。
#include
using
namespace std;
typedef
unsigned
long
long ull;
ull read()
const
int n=
200100
;ull n,k,lim,tot,t,ans;
ull f1[n]
,f2[n]
,pri[n]
;void
init
(ull x)
}void
work
(ull pos,ull res,ull rem)}}
intmain()
return0;
}
好吧,如果你看懂了上面那道題,那麼再來一道?loj6053 簡單的函式
這道題和上一道也差不多,就是我們要計算出質數異或1的字首和。
於是我們可以篩出質數字首和以及質數個數字首和。由於質數中偶數只有2,那麼只有2異或1後會加1,其他都會減1,這樣就能夠把質數異或1的字首和求出來了。
#include
using
namespace std;
typedef
long
long ll;
const ll mod=
1000000007
,div2=
500000004
;const
int n=
100005
;ll n,lim,tot,ans,f1[n]
,f2[n]
,s1[n]
,s2[n]
,pri[n]
;ll mul
(ll a,ll b)
ll sum
(ll x)
void
init()
for(ll i=lim/p+
1;i<=n/p/p&&i<=lim;
++i)
for(ll i=lim;i>=p*p;
--i)
}for
(ll i=
1;i<=lim;
++i)
}void
work
(ll pos,ll res,ll rem)}}
intmain()
bzoj5244
51nod 1847
uoj188
loj572
51nod 1965
51nod 1222
總結 篩法 Min 25篩
對於積性函式f x f x f x 求 i 1i n f i 其中n 1011 左右 sum f i 其中n leq 10 左右 i 1 i n f i 其 中n 1 011左 右 必須滿足的條件是 當p為質數時,f p f p f p 必須能表示為乙個多項式的形式,即f p a0 a1p a2p ...
演算法 Min 25篩
本篇文章中使用的字母 p 指 text p in text 若函式 f x 滿足,f x 是積性函式 f p 可以使用多項式表示。已知 f p 要能在常數級的時間內計算 f p x x in n min 25篩可以在 theta frac 的時間複雜度內計算 f x 的字首和 或者說 theta n...
LOJ 6202 葉氏篩法 min 25 篩
求 l,r 之間的素數之和 l 10 2 10 le r le 10 乙個有點裸的min 25篩?現在我只會篩素數的字首和 合數的過幾天再學吧 首先推薦一波yyb大佬部落格這個人很強 別那麼fake就好啦 令 f x x 顯然此處 f x 是完全積性函式 我們需要求的就是 displaystyle ...