zoukankan      html  css  js  c++  java
  • 数论入门1——莫比乌斯函数,欧拉函数,狄利克雷卷积,线性筛,莫比乌斯反演,杜教筛

    数论入门1

    一个菜鸡对数论的一点点理解...

    莫比乌斯函数

    定义函数(mu(n))为:

    1. 当n有平方因子时,(mu(n)=0)
    2. 当n没有平方因子时,(mu(n)=(-1)^{omega(n)})(omega(n))表示n不同质因子的个数。

    性质1:

    (sum_{d|n}mu(d)=[n=1])

    证明:我们把n分解质因数,则原式(=(-1+1)^{omega(n)}=0)

    因为对于不同的质因子,只有选和不选两种方案,这是一个组合数相加的形式,偶数加奇数减,根据二项式定理得到原式(=(-1+1)^{omega(n)}=0)

    但是(n=1)时,没有质因子,原式(=)$ 0choose0$$=1$。

    性质2:

    (mu(n))是积性函数。

    证明显然。

    欧拉函数

    定义函数(varphi(n))为:小于等于n的正整数中和n互质的数的个数。

    那么根据欧拉函数的定义,再根据上面的性质,我们可以在(O(sqrt n))的时间内通过分解质因数得到(varphi(n))

    具体方法,对于每个不同的质因子,相当于把它在1-n中的倍数去掉,那么就有(n*(1-frac{1}{pi}))个,连乘起来即可。

    性质1:

    对于质数p,(varphi(p)=p-1)

    性质2:

    对于质数p,(varphi(p^k)=(p-1)*p^{k-1})

    证明:首先,对于(p|n,q< p,qperp p),则(q+pkperp n)

    那么这就很显然了。

    性质3:

    (varphi)是个积性函数。

    根据定义式就能看出来。

    性质4:

    欧拉定理:对于互质的a,m有:(a^{varphi(m)} equiv 1 pmod {m})

    不会证明,自行百度。

    性质5:

    小于n且与n互质的正整数之和为(varphi(n)*n/2)

    证明:首先,若(p|n),则(n-p|n)

    那么对于所有p,把它和n-p合到一起算,就是(varphi(n)*n),最后除以2就行了,因为每对数算了两次。

    对于n=1不适用。

    性质6:

    (sumlimits_{d|n} varphi(d) = n)

    证明:

    (n=sum_{i|n} sum_{j=1}^n[gcd(j,n)=i])

    (=sum_{i|n}sum_{j=1}^{n/i}[gcd(j,n)=1])

    (=sum_{i|n}varphi(n/i))

    (=sum_{i|n}varphi(i))

    得证。

    其中第一句就是,把1-n中的数按照gcd进行分类并且计数。

    狄利克雷卷积

    定义卷积((f*g)(n)=sum_{d|n}f(d)g(frac{n}{d}))

    性质1:

    两个积性函数的狄利克雷卷积还是积性函数。

    证明:感性理解一下,两个互质的下标乘起来,相当于两个和式乘起来,因为是互质的相当于枚举到了乘积的所有约数,因为和式里面都是积性函数所以乘起来也是积性函数。

    性质2:

    三大运算规律:结合律,交换律,分配律。

    感性理解一下就好啦。

    然后给一点常用函数吧,杜教筛和莫比乌斯反演的时候有点用的。

    1. (mu(n)),不解释了。
    2. (varphi(n)),不解释了。
    3. (sigma(n)),表示n的约数和。
    4. (d(n)),表示n的约数个数。
    5. (e(n)),等于([n=1])
    6. (I(n)),等于1。
    7. (id(n)),等于n。

    其中后三个是完全积性函数。

    然后给点公式吧。

    (mu*I=e)

    (varphi*I=id)

    (id*mu=varphi)

    (I*I=d)

    (I*id=sigma)

    (varphi(n)=mu*id quad->quadfrac{varphi(n)}{n}=sum_{d|n}frac{mu(d)}{d})

    还有一些就不列举啦(其实是不会

    线性筛

    一种可以在(O(n))时间内求一个积性函数在1-n的值的算法,顺便还可以求出1-n中的素数表。

    因为保证了每个数只会被它的最小质因子筛到。

    代码实现:

    void getprime()
    {
        for(int i=2;i<=n;i++)
        {
            if(!vis[i]) pri[++tot]=i,mu[i]=-1,phi[i]=i-1;
            for(int j=1;j<=tot&&i*pri[j]<=n;j++)
            {
                vis[i*pri[j]]=1;
                if(i%pri[j]==0)
                {
                    mu[i*pri[j]]=0;
                    phi[i*pri[j]]=phi[i]*pri[j];
                    break;
                }
                mu[i*pri[j]]=-mu[i];
                phi[i*pri[j]]=phi[i]*(pri[j]-1);
            }
        }
    }
    

    就解释一句吧。

    if(i%pri[j]==0){break;}
    

    这一句是什么呢。质数表是递增的,如果i是pri[j]的倍数了,那么后面的i*pri[k]的最小质因子绝对不可能是pri[k],而在之后一定会被筛到,所以就要break掉了。

    所以我们可以看出,这个i只是起到了枚举质数倍数几倍的作用,这就很清晰了。

    然后一个积性函数f能够线性筛的话,需要满足的性质有:

    1.对于质数p,(f(p))能够快速计算。

    2.对于n中出现过的一个质因子p,(f(n*p))能够快速计算。

    然后如果需要有辅助函数的话,辅助函数也一定要是积性函数,一般都是维护最小质因子的辅助函数,比如筛约数个数,那么我们维护最小质因子的出现次数就可以很容易计算啦。

    莫比乌斯反演

    已知(F(n)=sum_{d|n}f(d))

    那么(f(n)=sum_{d|n}mu(d)F(frac{n}{d}))

    证明:

    (F=f*I)

    (F*mu=f*I*mu)

    (F*mu=f*e)

    (F*mu=f(n))

    得证。

    同理,已知(F(n)=sum_{n|d}f(d))

    那么(f(n)=sum_{n|d}mu(frac{d}{n})cdot F(d))

    不过做题的时候用的最多的还是两种函数的性质,直接反演用的比较少啦。

    整除分块

    一种可以在(O(sqrt n))时间内求上界与除法下取整有关的式子的算法。

    问题:求(sum_{i=1}^nlfloorfrac{n}{i} floor,nleq1e9)

    我们先发现一点关于(lfloorfrac{n}{i} floor)的性质。

    1. 对于(lfloorfrac{n}{i} floor),只有(2sqrt n)种取值。
    2. (lfloorfrac{n}{j} floor=lfloorfrac{n}{i} floor),则(j)的最大值为(large left lfloor frac N{left lfloor frac Ni ight floor } ight floor)

    证明:

    第一个,对于小于(sqrt n)(i),显然最多产生两个贡献(lfloorfrac{n}{i} floor)(i),所以是(2sqrt n)

    第二个:

    (large{ lfloor frac Ni floor}=k),于是可以写成(ki+p=N,1le p<i)的形式,若(large{lfloor frac N{i+d} floor}=k),于是有 (k(i+d)+p'=N),可以得到(p'=p-kd),则(d)能取的最大值为(large lfloor frac pk floor),于是 :

    [egin{aligned}i'&=i+d_{max} \ &=i+lfloor frac pk floor \&=i+left lfloor frac {N ;mod; i}{lfloor frac Ni floor} ight floor \ &=i+left lfloor frac {N-lfloor frac Ni floor i}{lfloor frac Ni floor} ight floor \ &=left lfloor i + frac {N-lfloor frac Ni floor i}{lfloor frac Ni floor} ight floor \ &=left lfloor frac{lfloor frac Ni floor i}{lfloor frac Ni floor} + frac {N-lfloor frac Ni floor i}{lfloor frac Ni floor} ight floor \ &=left lfloor frac N{lfloor frac Ni floor} ight floor quad quadend{aligned} ]

    [我太菜了不会证,搬别人的]

    贴段代码,解决上面的问题。

    for(int l=1,r;l<=n;l=r+1)
    {
        r=n/(n/l);
        ans+=(r-l+1)*(n/l);
    }
    

    杜教筛

    杜教筛是一种可以在低于线性时间内计算一类积性函数前缀和的算法。

    (S(n)=sum_{i=1}^{n}f(i))

    然后我们找一个积性函数(g(i))

    ((g*f)(i)= sum_{d|i}g(d)f(frac{i}{d}))

    (sum_{i=1}^{n}(g*f)(i)= sum_{i=1}^nsum_{d|i}g(d)f(frac{i}{d}))

    和式变换一下

    (sum_{d=1}^{n}g(d)sum_{d|i}f(frac{i}{d}))

    (sum_{d=1}^{n}g(d)sum_{i=1}^{n/d}f(i))

    (sum_{d=1}^ng(d)S(frac{n}{d}))

    我们现在要求(S(n))

    然后发现,当(d=1)时,有个(g(1)S(n))

    那么我们提出来

    (g(1)S(n)=sum_{i=1}^ng(i)S(frac{n}{i})-sum_{i=2}^ng(i)S(frac{n}{i}))

    (g(1)S(n)=sum_{i=1}^n(g*f)(i)-sum_{i=2}^ng(i)S(frac{n}{i}))

    那么只要两个函数卷积的前缀和很好算,g的前缀和很好算,就可以直接记忆化了。

    复杂度不会证,是(O(n^frac{3}{4}))的,如果预处理前(n^frac{2}{3})项的话,复杂度就变成了(O(n^frac{2}{3}))

    那么如果要筛(mu)的话,我们知道(mu)(I)的卷积十分好算,然后(I)的前缀和也很好算,可以试试:

    (S(n)=1-sum_{i=2}^{n}S(frac{n}{i}))

    对这就完了。

    (varphi)也挺简单的,和(I)卷积。

    (S(n)=sum_{i=1}^{n}i-sum_{i=2}^{n}S(frac{n}{i}))

    对于不同的积性函数,配上一个好的g函数,能方便很多。

    常见套路就是比如说有个(i*f(i)),那么我们拿id求个卷积,是不是i就被消掉了呢?

    如果是(i^2)也可以考虑用(g(i)=i^2)来做卷积。

    以此类推啦。

    题目

    挖个坑,待填

  • 相关阅读:
    15. DML, DDL, LOGON 触发器
    5. 跟踪标记 (Trace Flag) 834, 845 对内存页行为的影响
    4. 跟踪标记 (Trace Flag) 610 对索引组织表(IOT)最小化日志
    14. 类似正则表达式的字符处理问题
    01. SELECT显示和PRINT打印超长的字符
    3. 跟踪标记 (Trace Flag) 1204, 1222 抓取死锁信息
    2. 跟踪标记 (Trace Flag) 3604, 3605 输出DBCC命令结果
    1. 跟踪标记 (Trace Flag) 1117, 1118 文件增长及空间分配方式
    0. 跟踪标记 (Trace Flag) 简介
    SpringBoot + Redis + Shiro 实现权限管理(转)
  • 原文地址:https://www.cnblogs.com/CK6100LGEV2/p/10308116.html
Copyright © 2011-2022 走看看