线性筛法与积性函数


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


线性筛法

//线性筛法求质数。
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...<pn k1,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。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值