速通莫反

· · 算法·理论

一.积性函数

TIP. 其实这部分并不是太重要,只需要记得这些函数的定义和怎么用线性筛 O(n) 求解即可。

(1).定义

积性函数:对于函数 f(x),若 \forall a,b\in\mathbb{N}^+,\gcd(a,b)=1,f(ab)=f(a)f(b),则称 f(x) 为积性函数。

完全积性函数:对于函数 f(x),若 \forall a,b\in\mathbb{N}^+,f(ab)=f(a)f(b),则称 f(x) 为完全积性函数。

其中:\varepsilon(n)=\left[n=1\right],I(n)=1,id(n)=n

积性函数的性质:

则:

d(n)=(1+\alpha_1)\times(1+\alpha_2)\times\dots\times(1+\alpha_n) \sigma(n)=(1+p_1^1+p_1^2+\dots+p_1^{\alpha_1})\times(1+p_2^1+p_2^2+\dots+p_2^{\alpha_1})\times\dots\times(1+p_n^1+p_n^2+\dots+p_n^{\alpha_1}) =\prod\limits_{i=1}^n(\sum_{j=0}^{\alpha_i}p_i^j) =\prod\limits_{i=1}^n\frac{1-p_i^{\alpha_i+1}}{1-p_i}

2.求法

  1. 线性筛求 d
```cpp void make_d(){ t[1]=d[1]=1; for1(i,2,n){ if(!vis[i]) pri.p_b(i),t[i]=1,d[i]=2; for(int j: pri){ if(i>n/j) break; vis[i*j]=1; if(i%j==0){ t[i*j]=t[i]+1; d[i*j]=d[i]*(t[i*j]+1)/(t[i]+1); break; } t[i*j]=1; d[i*j]=d[i]*d[j]; } } } ``` 2. 线性筛求 $\sigma ```cpp void make_sgm(){ sigma[1]=1; for1(i,2,n){ if(!vis[i]) pri.p_b(i),t[i]=i+1,sigma[i]=i+1; for(int j: pri){ if(i>n/j) break; vis[i*j]=1; if(i%j==0){ t[i*j]=t[i]*j+1; sigma[i*j]=sigma[i]*t[i*j]/t[i]; break; } t[i*j]=j+1; sigma[i*j]=sigma[i]*sigma[j]; } } } ``` # 二.数论分块 [oi-wiki](https://oi-wiki.org/math/number-theory/sqrt-decomposition/) 一般用来求形如 $\sum_{i=1}^nf(i)g(\lfloor\frac{n}{i}\rfloor)

若可以 O(1) 计算 f(r)-f(l) 时。

我们考虑将 \lfloor\frac{n}{i}\rfloor 相同的数分块计算以使复杂度降至 O(\sqrt n\times poly(n))

其中的 poly(n) 是计算 g(i) 一次的复杂度。

最简单的例子: \sum_{i=1}^n\lfloor\frac{n}{i}\rfloor

证:按 \lfloor\frac{n}{i}\rfloor 相同的数分块数是 \sqrt{n} 量级的。

i\le \sqrt{n}\lfloor\frac{n}{i}\rfloor=\lfloor\frac{n}{1}\rfloor\dots\lfloor\frac{n}{\sqrt{n}}\rfloor\ge\sqrt{n} 最多有 \sqrt{n} 个取值。

i> \sqrt{n}\lfloor\frac{n}{i}\rfloor<\sqrt{n} 最多有 \sqrt{n} 个取值。

证毕。

所以数论整除可以将 O(n) 降为 O(\sqrt{n})

例题:UVA11526 H(n)

LL H(LL n){
    LL ans=0;
    for(LL i=1,j;i<=n;i=j+1){
        j=n/(n/i);
        ans+=(j-i+1)*(n/i);
    }
    return ans;
}

三.狄利克雷卷积

- 满足: - 交换律 - 结合律 - 分配率 - 单位元:$f\ast\varepsilon=f$ - $f\ast g$ 也是积性函数 - 若 $f\ast g=\varepsilon$,则称 $g(x)$ 是 $f(x)$ 的逆元,若 $f(x)$ 为积性函数,则 $g(x)$ 为积性函数 ###### 例子:

\begin{aligned} \epsilon=\mu\ast1&\iff\epsilon(n)=\sum\limits{d\mid n}\mu(d)\ d=1\ast1&\iff d(n)=\sum\limits{d\mid n}1\ \sigma=id\ast1&\iff\sigma(n)=\sum\limits{d\mid n}d\ \varphi=\mu\ast id&\iff\varphi(n)=\sum\limits{d\mid n}d\cdot\mu(\frac{n}{d}) \end{aligned}

****** 但是这么多函数之间进行狄利克雷卷积,很难记住结果怎么办? 有一种利用生成函数辅助的方法。 令 $p$ 表示任意质数。 首先我们有 $(f\ast g)(p^k)=\sum\limits_{k_1+k_2=k}f(p^{k_1})g(p^{k_2})$ 定义生成函数 $\tilde{f}(x)=\sum_{k}f(p^k)x^k$ 则 $\tilde{f\ast g}=\tilde{f}\cdot\tilde{g}$ 首先积性函数只需考虑定义域为 $p^k$ 的值,所以以下函数定义域均为 $p^k$ - $\tilde\mu(x)=1-x$ - $\tilde I(x)=1+x+x^2+\dots=\frac{1}{1-x}$ - $\tilde\varepsilon(x)=1$ - $\tilde\varphi(x)=1+(p-1)x+p(p-1)x^2+p^2(p-1)x^3+\dots=\frac{1-x}{1-px}$ - $\tilde {id}(x)=1+px+p^2x^2+\dots=\frac{1}{1-px}$ 这些函数之间的狄利克雷卷积的结果即为对应生成函数乘积所对应的函数了。 # 四.莫比乌斯变换 1. $f(n)=\sum\limits_{d\mid n}g(d)\iff g(n)=\sum\limits_{d\mid n}\mu(d)f(\frac{n}{d})$ 2. $f(n)=\sum\limits_{d\mid n}g(d)\iff g(n)=\sum\limits_{n\mid d}\mu(\frac{n}{d})f(d)$ 3. 反演结论: - $\sum\limits_{d\mid n}\mu(d)=\left[n=1\right]$ - $\sum\limits_{d\mid n}\varphi(d)=n$ 然后就是愉快的推式子环节了。 这块就先咕掉了。 因为主播都写在纸上了,没有时间转化成电子式子,并且用电脑推式子也很麻烦,有时间扫描成图片发一下吧,可能会放在别的地方。 题单:[莫比乌斯反演典题](https://www.luogu.com.cn/training/703911#problems) ****** # 五.杜教筛 ## 1.介绍 若要求积性函数 $f$ 的前缀和 $sf$。 找到一个积性函数 $g$,考虑其狄利克雷卷积的前缀和

\begin{aligned} &\sum\limits{i=1}^n(f\ast g)(i)\ &=\sum\limits{i=1}^n\sum\limits{d\mid i}f(d)g(\frac{i}{d})\ &=\sum\limits{d=1}^n g(d)\sum\limits{i=1}^{\lfloor\frac{n}{d}\rfloor}f(i)\ &=\sum\limits{d=1}^n g(d)sf(\lfloor\frac{n}{d}\rfloor) \end{aligned}

于是就有:$g(1)sf(n)=\sum\limits_{i=1}^n (f\ast g)(i)-\sum\limits_{i=2}^n g(i)sf(\lfloor\frac{n}{i}\rfloor)$ 这个公式称为杜教筛公式。 如果构造得当,那么 $\sum\limits_{i=1}^n (f\ast g)(i)$ 和 $sg(n)=\sum_{i=1}^n g(i)$ d都是可以 $O(1)$ 求出的。 具体的,我们设置一个函数 $GS(n)$ 求出 $sf(n)$ 的值,然后递归调用即可。 时间复杂度:$O(n^{\frac{3}{4}})$ ```cpp LL GS(int n){ LL ans=fg_sum(n); for(LL l=2,r;l<=n;l=r+1){ r=(n/(n/1)); ans-=(g_sum(r)-g_sum(l-1))*GS(n\l); } return ans; } ``` ## 2.进一步优化 但这样可能优化的不是很多,所以我们再添加一些技巧来进一步优化。 先线性筛求出前 $n^{\frac{2}{3}}$ 个答案,之后再用杜教筛,并配合记忆化,使得 $GS(i)$ 的每一个值都只计算一遍。 时间复杂度:$O(n^{\frac{2}{3}})$ ## 3.例题:求 $\mu$ 和 $\varphi$ 的前缀和 注意到 $\tilde\mu(x)=1-x,\tilde I(x)=1+x+x^2+\dots=\frac{1}{1-x}$,其乘积 $=1=\tilde\varepsilon(x)$ 所以令函数 $I$ 为杜教筛公式中的函数 $g$。 则 $\sum\limits_{i=1}^n (f\ast g)(i)= \sum\limits_{i=1}^n \varepsilon(i)=1$,$sg(n)=\sum_{i=1}^n I(i)=n$ 这样,我们就可以在 $O(n^{\frac{2}{3}})$ 的时间复杂度求出 $\sum_{i=1}^n \mu(i)$ 了。 同理,求 $\varphi$ 也是注意到 $\tilde\varphi(x)=1+(p-1)x+p(p-1)x^2+p^2(p-1)x^3+\dots=\frac{1-x}{1-px},\tilde I(x)=1+x+x^2+\dots=\frac{1}{1-x}$,其乘积 $=\frac{1}{1-px}=\tilde {id}(x)$ ```cpp int n,m; bool vis[N]; vector<int> pri; LL phi[N],mu[N]; void pre(int n){ phi[1]=mu[1]=1; for1(i,2,n){ if(!vis[i]) pri.pb(i),phi[i]=i-1,mu[i]=-1; for(int j: pri){ if(i>n/j) break; vis[i*j]=1; if(i%j==0){ phi[i*j]=phi[i]*j; mu[i*j]=0; break; } phi[i*j]=phi[i]*phi[j]; mu[i*j]=-mu[i]; } } for1(i,2,n) phi[i]+=phi[i-1],mu[i]+=mu[i-1]; } unordered_map<int,LL> ans_phi; unordered_map<int,int> ans_mu; LL GS_phi(LL n){ if(n<=(int)3e6) return phi[n]; if(ans_phi.count(n)) return ans_phi[n]; LL ans=1ll*n*(n+1)>>1ll; for(LL l=2,r;l<=n;l=r+1){ r=(n/(n/l)); ans-=1ll*(r-l+1)*GS_phi(n/l); } return ans_phi[n]=ans; } LL GS_mu(LL n){ if(n<=(int)3e6) return mu[n]; if(ans_mu.count(n)) return ans_mu[n]; LL ans=1; for(LL l=2,r;l<=n;l=r+1){ r=(n/(n/l)); ans-=1ll*(r-l+1)*GS_mu(n/l); } return ans_mu[n]=ans; } int x; void solve(){ cin>>x; cout<<GS_phi(x)<<" "<<GS_mu(x)<<"\n"; return ; } ``` ****** # 六、练习 好了,你已经学会莫反和杜教筛了,试着切掉以下这些水题吧。 求:$\sum_{i=1}^n\sum_{j=1}^m [\gcd(i,j)=k]$ - [P2522 [HAOI2011] Problem b](https://www.luogu.com.cn/problem/P2522) $f(a,b,k)=\sum_{t=1}^{\min(a,b)}\mu(t)\lfloor \frac{a}{tk} \rfloor\lfloor \frac{b}{tk} \rfloor$ $ans=f(b,d,k)-f(b,c-1)-f(a-1,c)+f(a-1,c-1)$ - [P3455 [POI 2007] ZAP-Queries](https://www.luogu.com.cn/problem/P3455) $ans(k)=\sum_{t=1}^n\mu(t)\lfloor \frac{n}{tk} \rfloor\lfloor \frac{n}{tk} \rfloor$ - [P4450 双亲数](https://www.luogu.com.cn/problem/P4450) 同上 *** 求:$\sum_{i=1}^n\sum_{j=1}^m\gcd(i,j)$ - [P1447 [NOI2010] 能量采集](https://www.luogu.com.cn/problem/P1447) $f(a,b)=\sum_{t=1}^n\varphi(t)\lfloor \frac{n}{t} \rfloor\lfloor \frac{n}{t} \rfloor$ $ans=2\times f(a,b)-a\times b$ - [P2398 GCD SUM](https://www.luogu.com.cn/problem/P2398) $ans(a,b)=\sum_{t=1}^n\varphi(t)\lfloor \frac{n}{t} \rfloor\lfloor \frac{n}{t} \rfloor$ ****** 求:$\sum_{i=1}^n\sum_{j=1}^mi\times j\gcd(i,j)$ - [P3768 简单的数学题](https://www.luogu.com.cn/problem/P3768) $ans(n)=\sum_{d=1}^n\varphi(d)d^2sum^3(\lfloor\frac{n}{d}\rfloor)$ ****** 求:$\sum_{i=1}^n\sum_{j=1}^mlcm(i,j)$ - [P1829 [国家集训队] Crash的数字表格 / JZPTAB](https://www.luogu.com.cn/problem/P1829) $ans(n,m)=\sum_{T=1}^nT\times sum^1{\lfloor\frac{n}{T}\rfloor}\times sum^1{\lfloor\frac{m}{T}\rfloor}\sum_{d\mid T}d\times\mu(d)$ 令 $f(T)=\sum_{d\mid T}d\times\mu(d)$ $f(p)=1-p,f(p^k)=f(p)$ $ans(n,m)=\sum_{T=1}^nT\times f(T)\times sum^1{\lfloor\frac{n}{T}\rfloor}\times sum^1{\lfloor\frac{m}{T}\rfloor}$ ****** 求:$\sum_{i=1}^n lcm(i,n)$ - [P1891 疯狂 LCM](https://www.luogu.com.cn/problem/P1891) $ans(n)=\frac{n}{2}(\sum_{d\mid n}d\times\varphi(d)+1)$ 令 $g(T)=\sum_{d\mid T}d\times\varphi(d)$ $g(p)=1+p\times(p-1),g(p^k)=g(p^{k-1})+p^{2k-1}(p-1)$ ****** 求:$\sum_{i=1}^n\sum_{j=1}^md(i\times j)$ - [P3327 [SDOI2015] 约数个数和](https://www.luogu.com.cn/problem/P3327) $ans(n,m)=\sum_{d=1}^n\mu(d)\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\lfloor\frac{n}{di}\rfloor\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor}\lfloor\frac{m}{dj}\rfloor$ 又有 $\sum_{i=1}^nd(i)=\sum_{j=1}^n\lfloor\frac{n}{j}\rfloor$ $\therefore ans(n,m)=\sum_{d=1}^n\mu(d)\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}d(i)\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor}d(j)$ ****** 求:$\prod_{i=1}^n\prod_{j=1}^mf(gcd(i,j)),f_0=0,f_1=1.f_n=f_{n-1}+f_{n-2},n\ge2$ - [P3704 [SDOI2017] 数字表格](https://www.luogu.com.cn/problem/P3704) $ans=\prod_{T=1}^n(\prod_{d\mid T}f(d)^{\mu(\lfloor\frac{T}{d}\rfloor)})^{\lfloor \frac{n}{T} \rfloor\lfloor \frac{m}{T} \rfloor}$ 内部的暴力预处理,外部数论分块。