• 数论函数基本知识


    基本符号

    1. ((a,b)=gcd(a,b))
    2. (a ot b Leftrightarrow (a,b)=1)
    3. ([mathrm{expr}]=0/1)如果表达式为真,那么值为(1),否则为(0).

    积性函数

    基本概念:对于一个数论函数(f(n)),当(n ot m)时,满足(f(nm)=f(n)f(m)),那么就称(f(n))是一个积性函数。

    完全积性函数:如果(n,m)不互质的时候仍然满足(f(nm)=f(n)f(m)),那么就称(f(n))是一个完全积性函数。

    完全积性函数是积性函数的一个子集

    一些基本的积性函数

    元函数(或称为单位元):(epsilon(n)=[n=1]),判断(n)是否为(1)

    恒等函数:(I(n)=1),无论(n)取何值,函数值都为(1)

    单位函数:(mathrm{id}(n)=n),等于(n)自身。

    欧拉函数:(varphi(n)=sumlimits_{i=1}^n [i ot n]),(n)以内和(n)互质的数的个数。

    欧拉函数存在一些简单有用的性质:

    [sumlimits_{d|n}varphi(d)=n\ sumlimits_{i=1}^n [i ot n] imes i=frac{n imesvarphi(n)}{2}\ varphi(nm)=frac{varphi(n)varphi(m)(n,m)}{varphi((n,m))} ]

    对于第二个性质,稍微给一个小证明:

    因为(gcd(x,n)=gcd(n-x,n))所以(n)以内和(n)互质的数一定成对出现,并且他们的和一定为(n),这样的数对一定有(cfrac{varphi(n)}{2})个,所以这些数的总和为(cfrac{n imesvarphi(n)}{2})

    莫比乌斯函数:(mu(i)),它的定义和求值方式之后再说。

    狄利克雷卷积

    现在有两个数论函数(f(n),g(n)),他们的狄利克雷卷积表示为((f*g)(n)),两个积性函数的卷积一定是一个积性函数。

    [(f*g)(n)=sumlimits_{d|n}f(d)g(frac{n}{d}) ]

    上面欧拉函数的其中一条性质用狄利克雷卷积表示就是((varphi*I)(n)=mathrm{id}(n))

    逆元:如果说((f*g)(n)=epsilon(n)),那么就称(f),(g)互为逆元,(g)可以写为(f^{-1})。一个积性函数的逆元一定是一个积性函数

    单位元:((f*epsilon)=f)

    结合律:((f*g)*k=f*(g*k))

    莫比乌斯反演

    首先解释一下,之前说的(mu(n)),其实就是(I(n))的逆元。接下来我们推一下这个函数的求值方式。

    因为(mu(n))是一个积性函数,所以可以分开每个质因子进行考虑。

    对于(mu(p^k))

    (k=0),易得(mu(1)=1),

    (k=1),因为((I*mu)(p)=0Rightarrow I(1)mu(p)+I(p)mu(1)=0Rightarrow mu(p)=-1)

    (k>2),可以得到

    [(I*mu)(p^k)=sum_{d=0}^k mu(p^d)I(p^{k-d})=sum_{d=0}^k mu(p^d) ]

    可以发现,如果(k=2),因为(mu(1)=1,mu(p)=-1),那么(mu(p^2)=0),以此类推,可以得到:

    [forall~~k>1, mu(p^k)=0 ]

    接着考虑所有正整数的情况:

    [对n进行质因数分解,得到n=prodlimits_{i=1}^n c_i^{k_i}\ mu(n)=egin{cases} 0 &存在k_i>1\ (-1)^n &otherwise end{cases} ]

    莫比乌斯反演,实际上是对于两个函数进行的变换:

    [F(n)=sumlimits_{d|n}f(d)Leftrightarrow f(n)=sumlimits_{d|n}mu(frac{n}{d})F(d) ]

    这个实际上证明非常简单,将其转化为狄利克雷卷积的形式:

    [egin{aligned} &F(n)=(f*I)(n)\ Rightarrow& (F*mu)(n)=(f*I*mu)(n)\ Rightarrow& (F*mu)(n)=f(n) end{aligned} ]

    小例题(有点难度)

    解法可能和莫比乌斯没有任何关系。

    给定一个正整数(n(nleq 10^{14})),计算

    [(sumlimits_{i=1}^nsumlimits_{d|i} gcd(d,frac{i}{d}))mod (10^9+7) ]

    直接画柿子即可:

    [egin{aligned} &sumlimits_{i=1}^n sumlimits_{d|i} (varphi*I)(gcd(d,frac{i}{d}))\ =&sumlimits_{i=1}^n sumlimits_{d|i} sumlimits_{k|d,k|frac{i}{d}} varphi(k)\ =&sumlimits_{i=1}^n sumlimits_{k^2|i} varphi(k) sumlimits_{d=1}^{lfloorfrac{n}{i} floor} 1\ =&sumlimits_{i=1}^n sumlimits_{k^2|i} varphi(k) imes lfloorfrac{n}{i} floor\ =&sumlimits_{k=1}^{lfloor{sqrt{n}} floor} varphi(k) sumlimits_{i=1}^{lfloor{frac{n}{k^2}} floor} lfloor{frac{n}{ik^2}} floor end{aligned} ]

    可以发现,前半部分可以使用前缀和进行计算,而后半部分可以使用整除分块。

    杜教筛

    现在我们需要求出一个积性函数的前缀和,
    假设为(f(n))
    (S_f(n)=sumlimits_{i=1}^n f(i))。如果n较小,可以使用线性筛求出。

    但是(n>10^7),现在需要一种较为快速的计算方法。

    由于(f)是一个积性函数,可以构造两个积性函数(g,h),满足((g*f)(n)=h(n))。而(g,h)都很容易求出。而(h)的前缀非常容易求出,而(g(1))的逆元很容易求。

    [egin{aligned} sumlimits_{i=1}^n h(i) &=sumlimits_{i=1}^n sumlimits_{d|i} f(i)g(frac{d}{i})\ &=sumlimits_{d=1}^n g(d) sumlimits_{i=1}^{lfloorfrac{i}{d} floor} f(i)\ &=sumlimits_{d=1}^n g(d) S_f(lfloor{frac{n}{d}} floor)\ &= g(1)S(n) + sumlimits_{d=2}^n g(d) S_f(lfloor{frac{n}{d}} floor)\ g(1)S(n) &= sumlimits_{i=1}^n h(i) - sumlimits_{d=2}^n g(d) S_f(lfloor{frac{n}{d}} floor) end{aligned} ]

    在实际实现的时候,在复杂度允许的情况下,用线性筛先将(n)较小的前缀和求出,在调用函数的时候,用一个unordered_map保存前缀和,就能加快运算。

    构造例子

    Example 1:(f ightarrow mu), 可以考虑构造(g ightarrow I, h ightarrow epsilon)

    Example 2:(f ightarrow varphi), 考虑式子((varphi*I)=mathrm{id}),构造(g ightarrow I,h ightarrow mathrm{id})

    Example 3:(f ightarrow mathrm{id} imesmu), 可以考虑构造(g ightarrow mathrm{id}),那么

    [egin{aligned} (g*f)(n) &=sumlimits_{d|n} g(frac{n}{d})f(d)\ &=sumlimits_{d|n} frac{n}{d} imes mu(d) imes d\ &= nsumlimits_{d|n} mu(d)\ &= n[n=1]\ &= epsilon(n) end{aligned} ]

    所以(h)函数就是(epsilon)

    Example 4:(f ightarrow mathrm{id}^2 imes varphi)
    构造(g(n)=mathrm{id}(n)^2), 那么可以得到:

    [egin{aligned} (f*g)(n) &=sumlimits_{d|n} g(frac{n}{d})f(d)\ &=sumlimits_{d|n} (frac{n}{d})^2 imes d^2 imes varphi(d)\ &=n^2 sumlimits_{d|n}varphi(d)\ &=n^3 end{aligned} ]

    所以(h)函数就是(mathrm{id}^3)

    附录:积性函数的线性筛法

    (varphi)为例:

    void init() {
      phi[1] = 1;
      for (int i = 2; i < MAXN; ++i) {
        if (!vis[i]) {
        	//i是一个质数
          phi[i] = i - 1;
          pri[cnt++] = i;
        }
        for (int j = 0; j < cnt; ++j) {
          if (1ll * i * pri[j] >= MAXN) break;
          vis[i * pri[j]] = 1;
          if (i % pri[j]) {
            phi[i * pri[j]] = phi[i] * (pri[j] - 1);
          } else {
            phi[i * pri[j]] = phi[i] * pri[j];
            break;
          }
        }
      }
    }
    
  • 相关阅读:
    值传递和引用传递(不是引用类型的传递)的区别
    字符串一旦定义,就表示开辟好了指定的空间,其内容就不可改变
    String类的直接赋值和构造方法赋值的区别
    字符串常量是String类的匿名对象
    Integer和int的区别(转)
    final的好处
    数组引用传递
    构造代码块
    ==和equals()的不同点
    Redis数据类型底层实现
  • 原文地址:https://www.cnblogs.com/juruohjr/p/13905122.html
Copyright © 2020-2023  润新知