积性函数与线性筛
積性函數與線性篩
積性函數
線性篩素數
保證每個數只會被它的最小質因子給篩掉(不同于埃氏篩中每個數會被它所有質因子篩一遍從而使復雜度過高)
所有線性篩積性函數都必須基于線性篩素數。
線性篩莫比烏斯函數
int mu[N],pri[N],tot,zhi[N]; void sieve() {zhi[1]=mu[1]=1;for (int i=2;i<=n;i++){if (!zhi[i]) pri[++tot]=i,mu[i]=-1;for (int j=1;j<=tot&&i*pri[j]<=n;j++){zhi[i*pri[j]]=1;if (i%pri[j]) mu[i*pri[j]]=-mu[i];else {mu[i*pri[j]]=0;break;}}} }線性篩歐拉函數
int phi[N],pri[N],tot,zhi[N]; void sieve() {zhi[1]=phi[1]=1;for (int i=2;i<=n;i++){if (!zhi[i]) pri[++tot]=i,phi[i]=i-1;for (int j=1;j<=tot&&i*pri[j]<=n;j++){zhi[i*pri[j]]=1;if (i%pri[j]) phi[i*pri[j]]=phi[i]*phi[pri[j]];else {phi[i*pri[j]]=phi[i]*pri[j];break;}}} }線性篩約數個數
記d(i)表示i的約數個數
d(i)=∏ki=1(ai+1)
維護每一個數的最小值因子出現的次數(即a1)即可
線性篩約數和
記σ(i)表示i的約數和
σ(i)=∏ki=1(∑aij=0pji)
維護low(i)表示i的最小質因子的指數次冪,即pa11,sum(i)表示i的最小質因子對答案的貢獻,即∑a1j=0pj1
(這玩意兒可能會爆int吧,我這里就不管那么多了)
線性篩一般積性函數
若想線性篩出積性函數f(x),就必須能夠快速計算出一下函數值:
1、f(1)
2、f§(p是質數)
3、f(pk)(p是質數)
其實就是含有的質因子數小于等于1的所有數對應的函數值。
常見的積性函數都會給出上述函數值的有關定義。對于自定義的一個積性函數(如狄利克雷卷積),就需要自行計算出上述函數值。
我們假設已經完成了上述函數值的計算,現在要求篩出所有至少含有兩個質因子的數對應的函數值。
顯然,一個含有至少兩個質因子的數一定可以被分解成兩個互質的且均不為1的數的乘積。此時我們就可以用f(xy)=f(x)f(y)計算得出相應的函數值。
以下內容需要完全理解上面的線性篩素數。
我們考慮篩的過程中,i?prij會被i乘上prij給篩掉。
若將i唯一分解得到pa11pa22…pakk,則一定有prij<=p1。
這個不需要證明,因為當prij=p1的時候就break掉了。
若prij<p1,則prij與i互質,可以直接f(i?prij)=f(i)?f(prij)
若prij=p1,這時就需要對i記錄一個lowi,表示i中最小值因子的指數次冪,即lowi=pa11(就是在唯一分解中的那個pa11)。
如果使用i除掉lowi那么結果中的最小質因子一定大于p1,而又因為prij=p1,從而可知gcd(i/lowi,lowi?prij)=1。那么就可以f(i?prij)=f(i/lowi)?f(lowi?prij)
注意當lowi=i時表示這個數是一個質數的若干次冪,這個時候就需要用到上方的特殊定義。
此外
對于某種形如狄利克雷卷積形式的函數∑d|xf(d)g(xd),若其中f(x)或g(x)不是積性函數,對于數據范圍較小(如106)的時候可以考慮暴力篩,即枚舉一個d去計算可以給哪些x做貢獻,復雜度是O(∑ni=1?ni?)即埃篩的復雜度。若數據范圍較大(107埃篩跑不過)就需要去考慮這個函數的一些相關性質了。
博客源地址https://www.cnblogs.com/zhoushuyu/p/8275530.html
總結
- 上一篇: php集成开发环境有哪些
- 下一篇: 数学--数论--HDU 4675 GCD