线性筛法与积性函数

来源:互联网 发布:自考本科 留学 知乎 编辑:程序博客网 时间:2024/05/16 17:15

神犇的博客:浅谈一类积性函数的前缀和


线性筛法

//线性筛法求质数。memset(mark,0,sizeof(mark));pt=0;for(int i=2;i<=N;i++){    if(!mark[i]){        prime[pt++]=i;        mark[i]=i;    }    for(int j=0,u=dmin(mark[i],N/i);j<pt&&prime[j]<=u;j++)        mark[prime[j]*i]=prime[j];}

marki 表示 i,除 1 以外的最小因子。
primei 维护质数序列。
保证 1~n 内的每一个合数被且只被除1外最小的因子筛过一次,对于当前处理到的 i 枚举小于marki 的所有质数,将后面的数筛过一遍。时间复杂度O(n)

证明正确性:每一个合数被且只被除1外最小的因子筛过一次。

设合数 P=p1^k1× p2^k2×p3^k3××pn^kn
其中p1,p2,p3...pn 为质数,且p1<p2<p3...<pnk1,k2,k3...kn 为正整数。

若P不是被 P’=p1^(k1-1)×p2^k2×p3^k3××pn^kn 经过 p1 筛到,
则任意一个除去一个其他因子pj得到的数都只能枚举到p1 。由已知条件,pj>p1,则无法筛到P。


积性函数
1.定义。若f(n) 是积性函数,则当gcd(a,b)=1f(a×b)=f(a)×f(b)
f(a×b)=f(a)×f(b) ,无限制条件,则f(n) 被成为完全积性函数。

2.性质。
1)gcd(a,b)=1f(a×b)=f(a)×f(b)
2)f(1)=1


欧拉函数
1.定义:这里写图片描述
其中p1, p2……pn为x的所有质因数(只出现一次),x是不为0的整数。

2.数学意义:φ(n) 表示表示 [1,n] 中n 的互质数个数。

3.性质。
1)φ(n)为积性函数,非完全积性。

2)欧拉定理:若gcd(a,p)=1 ,则aφ(p)1(modp)
费马小定理:若gcd(a,p)=1 ,且p是质数,则 ap11(modp)

3)d|nφ(d)=n 神犇的详解:法里级数展开证明

4)线性筛法原理:
φ(n)=ipki1i(pi1)

//线性筛法求欧拉函数。memset(phi,0,sizeof(phi));pt=0,phi[1]=1;for(int i=2;i<=N;i++){    if(!phi[i]){        prime[pt++]=i;        phi[i]=i-1;     }    for(int j=0,u=N/i;j<pt&&prime[j]<=u;j++)    {        if(i%prime[j]==0)        {            phi[prime[j]*i]=phi[i]*prime[j];            break;        }        else phi[prime[j]*i]=phi[i]*(prime[j]-1);    }}

莫比乌斯函数
神犇的详解

1.莫比乌斯反演:若f(d) 是积性函数,则如下g(n) 也是积性函数。
g(n)=d|nf(d)f(n)=d|nμ(d)g(nd)

2.应用:通过g(n) 的值推出f(d) 的值。

3.莫比乌斯函数μ(n)
1)函数式:d|nμ(d)=[n=1]
2)求解μ(m) :由积性函数性质拆分为若干μ(pk) 分别求解。有如下规律:μ(1)=1,μ(p)=1,μ(pk)=0(k>=2)

//线性筛法求莫比乌斯函数。memset(miu,0,sizeof(miu));memset(mark,0,sizeof(mark));pt=0,miu[1]=1;for(int i=2;i<=N;i++){    if(!mark[i]){        prime[pt++]=i;        miu[i]=-1;     }    for(int j=0,u=N/i;j<pt&&prime[j]<=u;j++)    {        mark[prime[j]*i]=1;        if(i%prime[j]==0)        {            miu[prime[j]*i]=0;            break;        }        else miu[prime[j]*i]=-miu[i];    }}

注: marki 表示是否是质数。


乘法逆元
1.定义:如果ax1(modp),且gcd(a,p)=1,则称 a 关于模 p 的乘法逆元为 x
2.应用。:
目标:求解 ab(modp) 的值。

gcd(a,b)=1,则无法用直接利用模运算求得。

k=f(b) (f(b)表示 b 在模 p 意义下的乘法逆元)
ab(modp) 等价于 a×k(modp) 可求解。

3.证明。
ax1(modp),且gcd(a,p)=1
p|(ax1) 等价于:ax1=py,yZ
写作 ax+py=1 不影响 x 解的结果。

通过exgcd求得x,y的整数解。

//扩展欧几里得算法求逆元。void exgcd(int a,int b,ll &x,ll &y){    if(b==0)x=1,y=0;    else    {        exgcd(b,a%b,x,y);        ll tmp=x;        x=(y+mod)%mod;        y=(tmp-(a/b)*y%mod+mod)%mod;    }}

若要求[1,n] 内所有数的乘法逆元?
exgcd的复杂度为 logn ,且有 nlnnnlogn 个质数。暴力exgcd就可以得出,但有更简单的方法。
神犇的证明

//线性筛法求逆元。inv[1]=1;for(int i=2;i<maxn;++i)    inv[i]=(p-p/i)*inv[p%i]%p;

终于都懂了!bravo。

原创粉丝点击