积性函数求和:筛法DP、洲阁筛

如果定义在正整数集上的函数 $f(n)$ 满足对于任意一对互素正整数 $n, m$ 都有 $f(n)f(m)=f(nm)$, 那么 $f$ 就叫做积性函数。

积性函数又可以表示为,假设 $n$ 的素因子分解式为 $n=\prod_{i=1}^mp_i^{c_i}$, 那么 $f(n)=\prod_{i=1}^mg(p_i, c_i)$.

本文讨论的函数满足:$g(p, c)$ 能够快速求单点值,且 $g(x, 1)$ 是关于 $x$ 的低次多项式。

积性函数求和,就是要求出 $\sum_{n=1}^N f(n)$.

筛法DP

我们先来看一道简单的例题。

求 $n$ 以内素数的个数 $\pi(n)$, 其中 $n \le 10^{11}$.

考虑用动态规划模拟筛法,筛掉最小素因子是 $2$ 的数,然后筛掉最小素因子是 $3$ 的数,以此类推……

于是我们可先预处理 $\sqrt n$ 以内的素数,从小到大记作 $p_1, p_2, \ldots, p_m$.

记 $p_{\min}(x)$ 表示 $x$ 的最小素因子,其中整数 $x>1$; 特别地,$p_{\min}(1)=+\infty$. 再记 $F(i, j)$ 表示满足 $p_{\min}(x)>p_i$ 且 $x \le j$ 的正整数 $x$ 的个数,也就是从 $1$ 到 $j$ 中筛掉 $p_1$ 至 $p_i$ 的倍数后剩余的数的个数。

那么合数和 $\sqrt n$ 以内的素数会被筛去,所以答案为 $m+F(m, n)-1$.

初值显然为 $F(0, j)=j$, $F(i, 0)=0$.

考虑最小素因子为 $p_i$ 的数,那么它可以表示为 $kp_i$, 其中 $k \le \left\lfloor{j \over p_i}\right\rfloor$, 且 $p_{\min}(k)>p_{i-1}$.

所以转移可写为 $F(i, j)=F(i-1, j)-F\left(i-1, \left\lfloor{j \over p_i}\right\rfloor\right)$.

这个DP尚停留在暴力阶段,考虑优化。

首先可以加入滚动数组优化。那么可写为:

$F_0(j)=j$

$F_i(j)=F_{i-1}(j)-F_{i-1}\left(\left\lfloor{j \over p_i}\right\rfloor\right)$.

这里,$F_i(j)$ 和 $F_{i-1}(j)$ 共用内存地址,下同。

由于 $\left\lfloor{\left\lfloor{n/a}\right\rfloor \over b}\right\rfloor=\left\lfloor{n \over ab}\right\rfloor$, 可知所有可能取得的 $j$ 都形如 $\left\lfloor{n \over a}\right\rfloor$. 当 $j \le \sqrt n$ 时,$j$ 的取值至多有 $\sqrt n$ 种;当 $j>\sqrt n$ 时,由于 $a<\sqrt n$, $j$ 的取值少于 $\sqrt n$ 种。因此,有用的 $j$ 少于 $2\sqrt n$ 个,由于 $m=\pi(\sqrt n)\sim\frac{n^{0.5}}{\ln n}$, 只计算这些 $j$, 就能把时间复杂度降为 $O\left({n \over \log n}\right)$, 空间复杂度降为 $O(\sqrt n)$.

考虑进一步优化。

根据定义,我们知道若 $j<p_i$, 则 $F_{i-1}(j)=1$.

进一步地,若 $p_i \le j<p_i^2$, 则 $F_i(j)=F_{i-1}(j)-1$, 换句话说,$F_i(j)+i=F_{i-1}(j)+(i-1)$.

于是我们改为记录 $F‘_i(j)=F_i(j)+i$, 这样,就只需重新计算满足 $p_i^2 \le j$ 的 $F‘_i(j)$.

那么这里需要计算的状态数有多少呢?注意到,$F‘_i(j)$ 需要计算当且仅当 $p_i^2 \le j \le n$, 也就是每个 $j \le n$ 都对应了 $\pi\left(\sqrt j\right)=O\left(\frac{j^{0.5}}{\log j}\right)$ 个 $i$.

对于所有可能的 $j$ 求和,得:

$$\begin{align}&\sum_{j=1}^{\lfloor\sqrt n\rfloor}O\left(\frac{j^{0.5}}{\log j}\right)+\sum_{a=1}^{\lfloor\sqrt n\rfloor}O\left(\frac{\lfloor n/a \rfloor^{0.5}}{\log\lfloor n/a \rfloor}\right)\\=&O\left(\sum_{a=1}^{\lfloor\sqrt n\rfloor}\frac{\lfloor n/a\rfloor^{0.5}}{\log\lfloor n/a \rfloor}\right)\\=&O\left(\frac{\int_{0}^{\sqrt n}\sqrt{n \over x}\mathrm dx}{\log n}\right)\\=&O\left(\frac{n^{0.75}}{\log n}\right)\end{align}$$

由上可知,时间复杂度降为 $O\left(\frac{n^{0.75}}{\log n}\right)$, 空间复杂度为 $O(\sqrt n)$.

我们考虑把此例的筛法DP推广到低次多项式上,也就是求 $n$ 以内所有素数 $p$ 的 $g(p, 1)$ 之和:

首先把不同幂次分开来算,假设现在要算的是 $n$ 以内所有素数的 $\alpha$ 次方的和。

处理出所有 $\sqrt n$ 内的素数,从小到大排列为 $p_1<p_2<\cdots<p_m$. 这些素数的 $\alpha$ 次方直接算,接下去需要考虑的就是不含 $\sqrt n$ 以内素因子的数的 $\alpha$ 次方之和,最后扣除 $1$.

记 $F_i(j)$ 表示所有满足 $p_{\min}(x)>p_i$ 且 $x \le j$ 的所有正整数 $x$ 的 $x^{\alpha}$ 之和。

初值 $F_0(j)=\sum_{k=1}^jk^{\alpha}$, 通过插值求出。

转移 $F_i(j)=F_{i-1}(j)-p_i^{\alpha}F_{i-1}\left(\left\lfloor{j \over p_i}\right\rfloor\right)$.

当 $j<p_i$ 时,$F_{i-1}(j)=1$.

进一步地,当 $p_i \le j<p_i^2$ 时,$F_i(j)=F_{i-1}(j)-p_i^{\alpha}$.

预处理 $\sum_{i=1}^kp_i^{\alpha}=S_k$, 可得 $F_i(j)+S_i=F_{i-1}(j)+S_{i-1}$, 于是记 $F‘_i(j)=F_i(j)+S_i$, 只需计算满足 $p_i^2 \le j$ 的 $F‘_i(j)$.

因此若不计插值的时间,求一次素数幂和的时间复杂度为 $O\left(\frac{n^{0.75}}{\log n}\right)$, 将每个幂和加起来即得到其在素数上的和。

洲阁筛

模仿筛法DP,设 $G_i(j)$ 表示所有满足 $p_{\min}(x) \ge p_i$ 且 $x \le j$ 的正整数 $x$ 的 $f(x)$ 之和。积性函数求和即求 $G_1(n)$.

筛法DP其实对于每个形如 $\left\lfloor{n \over a}\right\rfloor$ 的 $j$, 求出了不含 $\sqrt n$ 以内素因子的数 $x$ 的 $g(x, 1)$ 之和。我们将 $1$ 处的函数值修正,也就是给上述和加上 $1-g(1, 1)$, 得到初值 $G_{m+1}(j)$.

考虑枚举那些 $p_{\min}(x)=p_i$ 的数 $x$ 中 $p_i$ 的次数 $c$, 那么可以写为 $x=kp_i^c$, 其中 $k \le {j \over p_i^c}$, $p_{min}(k)>p_i$.

所以转移为 $G_i(j)=\sum_{c=0}^{\lfloor\log_{p_i}j\rfloor}g(p_i, c)G_{i+1}\left({j \over p_i^c}\right)$.

根据定义,当 $j<p_i$ 时,$G_i(j)=1$.

进一步地,当 $p_i \le j<p_i^2$ 时,$G_i(j)=G_{i+1}(j)+g(p_i, 1)$.

预处理 $S_i=\sum_{k=1}^ig(p_i, 1)$.

假设 $i_0$ 是最大的 $i$ 满足 $i \le m$ 且 $p_i \le j$. 这可以方便地求出:对 $j \le \sqrt n$ 预处理 $\pi(j)$, 可得 $i_0=\begin{cases}\pi(j),&j \le \sqrt n;\\m,&j>\sqrt n.\end{cases}$

因此 $G_i(j)+S_{i-1}=G_{i+1}(j)+S_i=\cdots=G_{i_0+1}(j)+S_{i_0}$.

所以当 $p_i \le j<p_i^2$ 且 $j \le \sqrt n$ 时,$G_i(j)=1+S_{\pi(j)}-S_{i-1}$; 当 $m<j<p_i^2$ 时,$G_i(j)=G_{m+1}(j)+S_m-S_{i-1}$.

因此只需考虑 $p_i^2 \le j$ 的状态,不然可以直接 $O(1)$ 计算得出。

枚举 $(i, j, c)$ 当且仅当 $i \le \min\{\sqrt j, \sqrt[c]j\}$, 由于 $\sum_{c=2}^{\lfloor\log_2j\rfloor}\pi\left(\sqrt[c]j\right)=O\left(\frac{j^{0.5}}{\log j}\right)$, 同筛法DP的复杂度分析可得这一部分的时间复杂度也为 $O\left(\frac{n^{0.75}}{\log n}\right)$.

总结

简单来说,洲阁筛分为下列几步:

  1. 取出所有形如 $\left\lfloor{n \over a}\right\rfloor$ 的正整数。
  2. 在 $\sqrt n$ 范围内预处理素数、素数个数 $\pi(j)$、素数的函数值前缀和。
  3. 筛法DP求最小素因子较大的数对应的函数值的和。
  4. 倒序筛法DP求范围内所有正整数的函数值的和。

其时间复杂度为 $O\left(\frac{n^{0.75}}{\log n}\right)$, 空间复杂度为 $O(\sqrt n)$.

模板题

LOJ6053 简单的函数

本题中,$g(x, c)=x \oplus c$. 特殊处理 $\sqrt n<2$ 的情况,否则对于 $p>\sqrt n\ge2$ 都有 $g(p, 1)=p-1$, 为低次多项式。接下来就可以全盘套用洲阁筛了。

代码链接

原文地址:https://www.cnblogs.com/nealchen/p/Sum-of-Multiplicative-Function.html

时间: 2024-07-30 14:58:09

积性函数求和:筛法DP、洲阁筛的相关文章

浅谈一类积性函数的前缀和(转载)

本文转自:http://blog.csdn.net/skywalkert/article/details/50500009 另外,莫比乌斯反演和杜教筛其他可转到 http://blog.leanote.com/post/totziens/%E8%8E%AB%E6%AF%94%E4%B9%8C%E6%96%AF%E5%8F%8D%E6%BC%94 写在前面 笔者在刷题过程中遇到一些求积性函数前缀和的问题,其中有一类问题需要在低于线性时间复杂度的算法,今天就来浅析一下这类问题的求解方法,当作以后讲课

读贾志鹏《线性筛法与积性函数》笔记

1.欧拉筛法在线性时间内求素数以及欧拉函数 代码: 1 procedure get; 2 var i,j,k:longint; 3 begin 4 tot:=0; 5 fillchar(check,sizeof(check),false); 6 for i:=2 to n do 7 begin 8 if not(check[i]) then 9 begin 10 inc(tot); 11 p[tot]:=i; 12 fai[i]:=i-1; 13 end; 14 for j:=1 to tot

积性函数筛法

积性函数筛法 很多常用的数论函数都是积性函数,而在题目中,我们常常需要线性(甚至更高)的筛法. 对于积性函数,我们可以在筛素数的基础上稍加修改,即可完成线性筛. 首先,注意到积性函数的特点: \[ f(xy)=f(x)\times f(y) \] 而可以线性筛的积性函数,需要知道以下两个式子的快速求法: \[ f(p)=?\quad f(p^k)=?\\p\in prime \] 其中, \(f(p)\) 大多是直接定义,\(f(p^k)\) 大多是递归定义. 我们来回忆一下素数筛的过程: in

hdu2421-Deciphering Password-(欧拉筛+唯一分解定理+积性函数+立方求和公式)

Deciphering Password Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2357    Accepted Submission(s): 670 Problem Description Xiaoming has just come up with a new way for encryption, by calculati

常用积性函数的线性筛法整理

简单整理推导加代码,留复习用. 线性筛素数 最简单也最基础,直接看代码就好了\(--\) code: void Euler_Phi_Prime(int n) { is_prime[1] = true; for (int i = 2; i <= n; i++) { if (!is_prime[i]) prime[++cnt] = i; for (int j = 1; j <= cnt && i * prime[j] <= n; j++) { is_prime[i * pri

POJ2480 Longge&#39;s problem 欧拉函数的应用 &amp;&amp; 积性函数

题意很简单,求sum(gcd(i,n))   1<=i<=n; 这题看到后第一反应并没有里用积性函数的性质,不过也可以做,欣慰的是我反应还是比较快的 设f(n)=gcd(1,n)+gcd(2,n)+....+gcd(n-1,n) + gcd(n,n), 用g(n,i)表示满足 gcd(x,n)=i的 x的个数 (x小于n),则 f(n)=sum{i*g(n,i)}; 同时又利用 扩展欧几里德的性质  gcd(x,n)=i  的充要条件是 gcd(x/i,n/i)==1,所以 满足 x/i的解有

HDU 4002 Find the maximum (欧拉函数-积性函数的性质(2011年大连赛区网络赛第二题)

[题目链接]:click here~~ [题目大意]: 给出一个整数n,求一个数x,x在1到n之间,并且x/φ(x)最大(其中φ(x)为x的欧拉函数). [思路]: 由欧拉函数为积性函数,即:如果 则有: 且: 则有: 要使f(x)最大,须使x含尽量多的不同素数因子. 代码: /* * Problem: HDU No.4002 * Running time: 1700MS * Complier: java * Author: javaherongwei * Create Time: 0:08 2

HDU 1452 Happy 2004(因子和的积性函数)

题目链接 题意 : 给你一个X,让你求出2004的X次方的所有因子之和,然后对29取余. 思路 : 原来这就是积性函数,点这里这里这里,这里讲得很详细. 在非数论的领域,积性函数指所有对于任何a,b都有性质f(ab)=f(a)f(b)的函数. 在数论中的积性函数:对于正整数n的一个算术函数 f(n),若f(1)=1,且当a,b互质时f(ab)=f(a)f(b),在数论上就称它为积性函数. 若对于某积性函数 f(n),就算a, b不互质,也有f(ab)=f(a)f(b),则称它为完全积性的. s(

spoj 3871. GCD Extreme 欧拉+积性函数

3871. GCD Extreme Problem code: GCDEX Given the value of N, you will have to find the value of G. The meaning of G is given in the following code G=0; for(k=i;k< N;k++) for(j=i+1;j<=N;j++) { G+=gcd(k,j); } /*Here gcd() is a function that finds the g